Разумны ли сотни/тысячи TCP-сокетов для memcached?
-
21-08-2019 - |
Вопрос
Я использую 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, похоже, у вас было ужасное количество потоков или вы неправильно его кэшируете.
Удачи!