Статьи

Создание идеальной тестовой среды для Кассандры

Месяц назад один из наших клиентов попросил нас установить 15 отдельных экземпляров Cassandra с одним узлом, каждый из которых будет размещаться в 64 МБ ОЗУ, а каждый — на одном компьютере. Мой первый ответ был «Почему !?»

Качества Идеальной Структуры Теста Кассандры

Так что являются качествами идеальной тестовой структуры Cassandra?

  • Легкий и доступный — хорошая тестовая среда потребует как можно меньше ресурсов и будет доступна в нужный момент.
  • Соотношение с производством . Тестовая среда должна идеально имитировать производственную среду. Это ежу понятно. В конце концов, что хорошего в том, что вы проходите тест, только чтобы задаться вопросом, скрывается ли ошибка в различиях между тестовой и рабочей средами?
  • Отсутствие состояния. Между выполнением тестов нет никаких причин хранить какую-либо информацию. Так почему бы просто не выбросить все это?
  • Изолированный — чаще всего в команде будет несколько разработчиков, и есть большая вероятность, что они будут тестировать одновременно. Важно держать каждого разработчика изолированным от других.
  • Устойчивость к сбоям — Помните, мы немного обеспокоены тем, что Кассандра будет боровом или просто не будет работать. Быть «устойчивым к ошибкам» означает достичь правильного баланса, чтобы Кассандра занимала как можно меньше ресурсов, не теряя при этом своих возможностей.

Реализация тестовой среды Ideal Cassandra

Первое, что нужно сделать, это настроить тестовую среду для каждого разработчика. Это означает изменение нескольких путей. От cassandra.yaml, поменяй

data_file_directories: - /home/jberryman/cassandra/data commitlog_directory: /home/jberryman/cassandra/commitlog saved_caches_directory: /home/jberryman/saved_caches - See more at: http://www.opensourceconnections.com/2013/08/31/building-the-perfect-cassandra-test-environment/#sthash.ObFjHIup.dpuf

И тогда в log4j-server.properties меняются

log4j.appender.R.File=/home/jberryman/cassandra/system.log#sthash.ObFjHIup.dpuf

Далее, это хорошая идея — создать оболочку для любого клиента, который вы используете. Это имеет несколько преимуществ. Во-первых, создание оболочки обеспечивает защиту от изменения клиента из-под вас. Это особенно важно сейчас, так как очень многие клиенты пытаются совместить CQL3. Эта обертка также является отличным местом для защиты от перегрузки ваших производственных данных, когда вы думаете , что запускаете тест. Возможно, самый простой способ защититься от этого — выпустить CQLDESCRIBE CLUSTERи убедитесь, что имя кластера «TestCluster». (Если ваш клиент CQL не соблюдает этот оператор, вы можете просто создать пространство ключей с именем «Yes_ThisIsIndeedATestCluster» и проверить его существование.) После того, как оболочка завершена, ее можно использовать с функциональной четностью как в тестовом, так и в производственном кластере.

Самый простой способ сделать Cassandra легким — просто заявить об этом! В cassandra-env.sh просто поменяй

MAX_HEAP_SIZE="64M" 
HEAP_NEWSIZE="12M"

Однако то, что вы теперь объявили Cassandra легким, не означает, что это будет Just Work ™. Учитывая это небольшое пространство кучи для перемещения, Cassandra с радостью выбросит вам ошибку OutOfMemory при первой очистке SSTable, сжатии или сборке мусора. Чтобы защититься от этого, у нас есть немного работы!

Первое, что нужно сделать, это уменьшить количество потоков, особенно для чтения и записи. В cassandra.yaml есть несколько изменений:

rpc_server_type: hsha 

Здесь hsha означает «наполовину синхронный, наполовину асинхронный». Это гарантирует, что все экономичные клиенты обрабатываются асинхронно с использованием небольшого числа потоков, которые не зависят от количества экономических клиентов.

concurrent_reads: 2; 
concurrent_writes: 2 
rpc_min_threads: 1; 
rpc_max_threads: 1

Как уже говорилось, первые две строки ограничивают количество операций чтения и записи, которые могут происходить одновременно. Два — это минимально допустимое количество. Вторые две строки ограничивают количество доступных потоков, используемых для обслуживания запросов. Все, что к этому моменту, служит для того, чтобы записи и чтения не могли подавить Кассандру во время приливов и уплотнений. Следующий:

concurrent_compactors: 1

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

Далее нам нужно убедиться, что мы делаем все возможное, чтобы не препятствовать уплотнению . Одна настройка здесь:

compaction_throughput_mb_per_sec: 0

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

Далее, мы поворачиваем все ручки на использование памяти как можно ниже:

in_memory_compaction_limit_in_mb: 1

Это минимальный предел, позволяющий выполнять сжатие в памяти. При таком низком значении большая часть сжатия будет выполняться в двухпроходном методе, который требует интенсивного ввода-вывода, но мы не беспокоимся о вводе-выводе!

key_cache_size_in_mb: 0

За счет времени чтения мы можем покончить с ключевыми кешами. Но это может даже не быть необходимым, потому что мы можем сделать еще лучше:

reduce_cache_sizes_at: 0 
reduce_cache_capacity_to: 0 

Первая строка гласит: «Как только вы израсходуете столько памяти, уменьшите емкость кеша». И поскольку он установлен на ноль, емкость кеша уменьшается примерно, как только Cassandra начинает использоваться. Во второй строке указывается, что кэши не должны использоваться вообще.

Наконец, в тестовом кластере нас не беспокоит долговечность данных, поэтому существует множество мер безопасности, с которыми мы можем просто отказаться. Например, перед запуском тестового кластера удалите все из каталогов data dir и commitlog. Далее в cassandra.yaml установлено hinted_handoff_enabled: false. При создании тестового пространства ключей продолжайте и установите durable_writes = falseтак, чтобы журнал фиксации никогда не заполнялся. Наконец, при создании тестовых таблиц, рассмотрите установку read_repair_chance = 0и bloom_filter_fp_chance = 1. Хотя, возможно, эти изменения в пространствах клавиш и таблицах не нужны, потому что я смог добиться довольно хорошей производительности без них.

Тестирование инфраструктуры тестирования

Теперь, когда все наши изменения внесены, давайте запустим Кассандру и посмотрим, как она работает!

$ rm -fr /home/jberryman/cassandra && bin/cassandra -f 

Пока все хорошо. «Начало прослушивания клиентов CQL на localhost / 127.0.0.1: 9042» означает, что мы живы и готовы обслуживать запросы. Пришло время хлопнуть Кассандрой

$ bin/cassandra-stress total,interval_op_rate,interval_key_rate,latency/95th/99th,elapsed_time 33287,3328,3328,8.0,54.6,277.0,10 85059,5177,5177,7.5,33.3,276.7,20 133153,4809,4809,7.4,34.0,274.8,30 183111,4995,4995,6.9,31.6,165.1,40 233177,5006,5006,6.8,32.0,123.5,51 288998,5582,5582,6.7,26.7,123.5,61 341481,5248,5248,6.7,26.3,129.7,71 391594,5011,5011,6.7,26.7,129.7,81 441645,5005,5005,6.5,29.0,122.5,92 494198,5255,5255,6.3,28.3,122.9,102 539406,4520,4520,6.4,24.4,122.9,112 591272,5186,5186,6.4,26.8,122.9,122 641202,4993,4993,6.6,27.9,122.9,132 696041,5483,5483,6.6,28.2,122.9,143 747078,5103,5103,6.5,26.1,274.4,153 797125,5004,5004,6.4,25.3,274.4,163 839887,4276,4276,6.1,23.9,273.6,173 880678,4079,4079,6.0,22.9,273.6,184 928384,4770,4770,5.8,21.7,273.6,194 979878,5149,5149,5.7,20.2,273.6,204 1000000,2012,2012,5.5,19.4,273.6,208 END 

Ух ты … так что он не только не умирает, но и чертовски хорош! Оглядываясь назад, я вижу пару предупреждений:

WARN 17:15:57,030 Heap is 0.5260566963447822 full. You may need to reduce memtable and/or cache sizes. Cassandra is now reducing cache sizes to free up memory. Adjust reduce_cache_sizes_at threshold in cassandra.yaml if you don't want Cassandra to do this automatically 

Ах … это связано с тем reduce_cache_sizes_at, reduce_cache_capacity_toнемного раньше. После этого предупреждения мы нажимаем, мы знаем, что кэши были выброшены. Без кешей мне интересно, как это повлияет на производительность чтения. Давайте посмотрим!

$ bin/cassandra-stress --operation READ total,interval_op_rate,interval_key_rate,latency/95th/99th,elapsed_time 34948,3494,3494,8.4,39.9,147.0,10 95108,6016,6016,7.9,19.3,145.2,20 155830,6072,6072,7.8,15.4,144.7,30 213037,5720,5720,7.8,14.6,72.5,40 274021,6098,6098,7.8,13.7,56.8,51 335575,6155,6155,7.7,12.6,56.6,61 396074,6049,6049,7.7,12.6,56.6,71 455660,5958,5958,7.7,12.7,45.8,81 516840,6118,6118,7.7,12.3,45.8,91 576045,5920,5920,7.7,12.3,45.6,102 635237,5919,5919,7.7,12.7,45.6,112 688830,5359,5359,7.7,13.5,45.6,122 740047,5121,5121,7.7,15.1,45.8,132 796249,5620,5620,7.8,14.8,42.4,143 853788,5753,5753,7.9,14.1,37.1,153 906821,5303,5303,7.9,15.1,37.1,163 963981,5716,5716,7.9,14.1,37.1,173 1000000,3601,3601,7.9,13.3,37.1,180 END 

Ура, это работает! И это все еще довольно быстро! Я был обеспокоен отсутствием кэшей, убивающих производительность чтения Кассандры, но, похоже, это просто отлично. Оглядываясь назад на файл журнала, вы увидите еще несколько предупреждений:

WARN 17:16:25,082 Heap is 0.7914885099943694 full. You may need to reduce memtable and/or cache sizes. Cassandra will now flush up to the two largest memtables to free up memory. Adjust flush_largest_memtables_at threshold in cassandra.yaml if you don't want Cassandra to do this automatically WARN 17:16:25,083 Flushing CFS(Keyspace='Keyspace1', ColumnFamily='Standard1') to relieve memory pressure 

Несмотря на то, что у нас регулярно случаются эти аварийные запоминающиеся приливы, Кассандра никогда не умирает !

Открыв jconsole, мы можем сделать еще пару замечаний. Во-первых, хотя неизмененный процесс Cassandra занимает примерно 8 ГБ памяти, этот тест Cassandra никогда не превышает 64 МБ. Во-вторых, мы также видим, что число потоков на неизмененной Кассандре колеблется в пределах 120-130, в то время как тест Кассандры остается где-то между 40 и 50.

Вывод

Итак, вы видите, запрос моего клиента был на самом деле вполне разумным и довольно хорошей идеей! Теперь у них есть тестовая среда, которая может поддерживать 15 разработчиков на одной машине, так что у каждого разработчика есть своя изолированная тестовая среда. Это хороший пример того, как консультанты иногда учатся у компаний, с которыми они консультируются.

Как вы тестируете Кассандру? Мы хотели бы знать!