Вопрос

Я использую Merb::Cache для хранения txt/xml и заметил, что чем дольше я оставляю свои merbs работающими, тем больше у меня открытых TCP-сокетов - я считаю, что это вызывает некоторые серьезные проблемы с производительностью.

lsof | grep 11211 | wc -l
494
merb      27206       root   71u     IPv4   13759908                 TCP localhost.localdomain:59756->localhost.localdomain:11211 (ESTABLISHED)
merb      27206       root   72u     IPv4   13759969                 TCP localhost.localdomain:59779->localhost.localdomain:11211 (ESTABLISHED)
merb      27206       root   73u     IPv4   13760039                 TCP localhost.localdomain:59805->localhost.localdomain:11211 (ESTABLISHED)
merb      27206       root   74u     IPv4   13760052                 TCP localhost.localdomain:59810->localhost.localdomain:11211 (ESTABLISHED)
merb      27206       root   75u     IPv4   13760135                 TCP localhost.localdomain:59841->localhost.localdomain:11211 (ESTABLISHED)
merb      27206       root   76u     IPv4   13760823                 TCP localhost.localdomain:59866->localhost.localdomain:11211 (ESTABLISHED)
merb      27206       root   77u     IPv4   13760951                 TCP localhost.localdomain:52095->localhost.localdomain:11211 (ESTABLISHED)

и т. д...

мой соответствующий код:

    if !exists?(:memcached) then
      register(:memcached, Merb::Cache::MemcachedStore, :namespace => 'mynamespace', :servers => ['127.0.0.1:11211'])
    end

&&

    when :xml
      unless @hand_xml = Merb::Cache[:memcached].read("/hands/#{@hand.id}.xml")
        @hand_xml = display(@hand)
        Merb::Cache[:memcached].write("/hands/#{@hand.id}.xml", @hand_xml)
      end
      return @hand_xml

этот код совершенно неправильный или я использую неправильную версию memcache??

У меня memcached 1.2.8 и у меня есть следующее:

libmemcached-0.25.14.tar.gz memcached-0.13.gem

это как то сводит меня с ума..

Это было полезно?

Решение

ок, я кое-что понял..

1) МОЖЕТ быть разумным иметь сотни/тысячи сокетов, подключенных к memcached, предполагая, что вы используете библиотеку, которая использует epoll или что-то еще - однако, если вы используете Ruby, как я, я не знаю о библиотеке, которая использует что-то кроме select() или poll() - поэтому возникает этот вопрос/немедленно нужно ответить

2) если вы похожи на меня, у вас сейчас работает только один сервер memcached и пара дворняг / ублюдков, бегающих вокруг, заботящихся о запросах ... поэтому ваши соединения с memcache должны быть проблематичными.быть не больше, чем количество дворняг/тонов, которые у вас работают (при условии, что вы кэшируете только 1 или два набора вещей) - как это было в моем случае

вот исправление:

настройте memcache через memcached gem, а не через merb::cache (который фактически оборачивает любую библиотеку memcache, которую вы используете

MMCACHE = Memcached.new("localhost:11211")

получить/установить ваши значения:

  @cache = MMCACHE.clone
  begin
    @hand_xml = @cache.get("/hands/#{@hand.id}.xml")
  rescue
    @hand_xml = display(@hand)
    @cache.set("/hands/#{@hand.id}.xml", @hand_xml)
  end
  @cache.quit

сядьте и выпейте холодную, потому что теперь, когда вы делаете это:

lsof | grep 11211 | wc -l

вы видите что-то вроде 2 или 3 вместо 2036!

подсказка, что подсказала мне, что соединения с кэшем памяти нередко бывают постоянными с самого начала.

Другие советы

Возможно, я смогу помочь, но для этого мне нужно рассказать историю.Вот.

Когда-то давно существовал кластер из 10 серверов Apache (ssl), настроенных на ровно 100 потоков каждый.Еще был кластер из 10 memcached-серверов (на тех же ящиках), и все они казалось жить мирно.И Apache, и Memcached охранялись злом. демон мониторинга.

Затем King установил 11-й сервер Apache(ssl), и memcached начал случайным образом перезапускаться каждые несколько часов!Король начал расследование и что он нашел?В документации модуля php memcache была ошибка, в которой говорилось, что конструктор по умолчанию объекта подключения Memcache нет настойчиво, но, видимо, так оно и было.Произошло следующее: каждый php-поток (а их было около 1000) открывал соединение с каждым memcached в пуле, когда оно ему было нужно, и удерживал его.К каждому memcached-серверу было 10*100 подключений и это было нормально, но при 11 серверах было 1100 и как 1024<1100.Максимальное количество открытых сокетов для memcached — 1024.Когда все сокеты были заняты, демон monit не смог подключиться, поэтому перезапустил memcached.

В каждой истории должна быть мораль.И что же со всем этим сделал король?Он отключил постоянные соединения, и с тех пор все они жили долго и счастливо, а количество соединений в кластере достигло максимума 5 (пять).Эти серверы обслуживали огромные объемы данных, поэтому у нас не было 1000 запасных сокетов, и было дешевле согласовывать соединение с кэшем памяти при каждом запросе.

Извините, но я не знаю Ruby, похоже, у вас было ужасное количество потоков или вы неправильно его кэшируете.

Удачи!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top