2016-03-02 5 views
0

FYI. Мы проводим этот тест с Cassandra 2.1.12.1047 | DSE 4.8.4LOCAL_ONE и непредвиденная репликация данных с Cassandra

У нас есть простая таблица в Кассандре, в которой содержится 5000 строк данных. Некоторое время назад, в качестве меры предосторожности, мы добавили мониторинг на каждый экземпляр Cassandra, чтобы убедиться, что он имеет 5000 строк данных, потому что наш коэффициент репликации обеспечивает это, т.е. у нас есть 2 реплики в каждом регионе, и у нас есть 6 серверов в нашем кластере dev.

CREATE KEYSPACE example WITH replication = {'class': 'NetworkTopologyStrategy', 'ap-southeast-1-A': '2', 'eu-west-1-A': '2', 'us-east-1-A': '2'} AND durable_writes = true;

Недавно мы принудительно отменялись сервер для имитации сбоя и принесли новый онлайн, чтобы посмотреть, что произойдет. Мы также удалили старый узел, используя nodetool removenode, чтобы в каждом регионе мы ожидали, что все данные будут существовать на каждом сервере.

Как только новый сервер вышел в сеть, он присоединился к кластеру и, похоже, начал реплицировать данные. Мы предполагаем, что в режиме начальной загрузки он будет отвечать за то, чтобы он получал нужные данные из кластера. Процессор, наконец, упал примерно через час, и мы предположили, что репликация завершена.

Однако наши мониторы, которые намеренно делают запросы с использованием LOCAL_ONE на каждом сервере, сообщили, что на всех серверах было 5000 строк, а новый сервер, который был подключен к сети, застрял около 2600 строк. Мы предположили, что, возможно, это все еще повторялось, поэтому мы оставили его на некоторое время, но он остался на этом уровне.

Так мы провели nodetool статус проверки и получил следующее:

$ nodetool status my_keyspace 
Datacenter: ap-southeast-1-A 
====================================== 
Status=Up/Down 
|/ State=Normal/Leaving/Joining/Moving 
-- Address   Load  Tokens Owns (effective) Host ID        Rack 
UN 54.255.17.28 7.9 GB  256  100.0%   a0c45f3f-8479-4046-b3c0-b2dd19f07b87 ap-southeast-1a 
UN 54.255.64.1  8.2 GB  256  100.0%   b91c5863-e1e1-4cb6-b9c1-0f24a33b4baf ap-southeast-1b 
Datacenter: eu-west-1-A 
================================= 
Status=Up/Down 
|/ State=Normal/Leaving/Joining/Moving 
-- Address   Load  Tokens Owns (effective) Host ID        Rack 
UN 176.34.207.151 8.51 GB 256  100.0%   30ff8d00-1ab6-4538-9c67-a49e9ad34672 eu-west-1b 
UN 54.195.174.72 8.4 GB  256  100.0%   f00dfb85-6099-40fa-9eaa-cf1dce2f0cd7 eu-west-1c 
Datacenter: us-east-1-A 
================================= 
Status=Up/Down 
|/ State=Normal/Leaving/Joining/Moving 
-- Address   Load  Tokens Owns (effective) Host ID        Rack 
UN 54.225.11.249 8.17 GB 256  100.0%   0e0adf3d-4666-4aa4-ada7-4716e7c49ace us-east-1e 
UN 54.224.182.94 3.66 GB 256  100.0%   1f9c6bef-e479-49e8-a1ea-b1d0d68257c7 us-east-1d 

Таким образом, если сервер сообщает, что он владеет 100% данных, почему это LOCAL_ONE запрос только дает нам примерно половину данных ?

Когда я запустил запрос LOCAL_QUORUM, он вернул 5000 строк, и с этого момента форварды вернули 5000 даже за LOCAL_ONE запросов.

В то время как LOCAL_QUORUM решил проблему в этом случае, мы можем в будущем выполнять другие типы запросов при условии, что каждый сервер a) имеет данные, которые он должен иметь, b) знает, как удовлетворять запросы, если это не имеют данные, то есть знают, что данные находятся где-то еще на ринге.

ДАЛЕЕ ОБНОВЛЕНИЕ 24 часа - ПРОБЛЕМА МНОГО ХУЖЕ

Таким образом, в отсутствие какой-либо обратной связи по этому вопросу, я продолжил экспериментировать с этим на кластере путем добавления дополнительных узлов. Согласно https://docs.datastax.com/en/cassandra/1.2/cassandra/operations/ops_add_node_to_cluster_t.html, я выполнил все шаги, рекомендованные для добавления узлов в кластер, и по сути добавить емкость. Я считаю, что предпосылка Cassandra заключается в том, что, добавляя узлы, ответственность кластера заключается в том, чтобы перебалансировать данные и за это время получить данные с позиции на кольце, если оно не там, где должно быть.

К сожалению, это совсем не так. Вот мое новое кольцо:

Datacenter: ap-southeast-1-A 
====================================== 
Status=Up/Down 
|/ State=Normal/Leaving/Joining/Moving 
-- Address   Load  Tokens Owns (effective) Host ID        Rack 
UN 54.255.xxx.xxx 8.06 GB 256  50.8%    a0c45f3f-8479-4046-b3c0-b2dd19f07b87 ap-southeast-1a 
UN 54.254.xxx.xxx 2.04 MB 256  49.2%    e2e2fa97-80a0-4768-a2aa-2b63e2ab1577 ap-southeast-1a 
UN 54.169.xxx.xxx 1.88 MB 256  47.4%    bcfc2ff0-67ab-4e6e-9b18-77b87f6b3df3 ap-southeast-1b 
UN 54.255.xxx.xxx 8.29 GB 256  52.6%    b91c5863-e1e1-4cb6-b9c1-0f24a33b4baf ap-southeast-1b 
Datacenter: eu-west-1-A 
================================= 
Status=Up/Down 
|/ State=Normal/Leaving/Joining/Moving 
-- Address   Load  Tokens Owns (effective) Host ID        Rack 
UN 54.78.xxx.xxx 8.3 GB  256  49.9%    30ff8d00-1ab6-4538-9c67-a49e9ad34672 eu-west-1b 
UN 54.195.xxx.xxx 8.54 GB 256  50.7%    f00dfb85-6099-40fa-9eaa-cf1dce2f0cd7 eu-west-1c 
UN 54.194.xxx.xxx 5.3 MB  256  49.3%    3789e2cc-032d-4b26-bff9-b2ee71ee41a0 eu-west-1c 
UN 54.229.xxx.xxx 5.2 MB  256  50.1%    34811c15-de8f-4b12-98e7-0b4721e7ddfa eu-west-1b 
Datacenter: us-east-1-A 
================================= 
Status=Up/Down 
|/ State=Normal/Leaving/Joining/Moving 
-- Address   Load  Tokens Owns (effective) Host ID        Rack 
UN 54.152.xxx.xxx 5.27 MB 256  47.4%    a562226a-c9f2-474f-9b86-46c3d2d3b212 us-east-1d 
UN 54.225.xxx.xxx 8.32 GB 256  50.3%    0e0adf3d-4666-4aa4-ada7-4716e7c49ace us-east-1e 
UN 52.91.xxx.xxx 5.28 MB 256  49.7%    524320ba-b8be-494a-a9ce-c44c90555c51 us-east-1e 
UN 54.224.xxx.xxx 3.85 GB 256  52.6%    1f9c6bef-e479-49e8-a1ea-b1d0d68257c7 us-east-1d 

Как вы видите, я в два раза размер кольца и эффективная доля владения составляет примерно 50% на сервер, как и ожидалось (мой коэффициент репликации 2-х экземплярах в каждом регионе). Тем не менее, вы можете видеть, что некоторые серверы абсолютно не загружают их (они новы), в то время как другие имеют чрезмерную нагрузку на них (они старые, и, очевидно, никакого распространения данных не произошло).

Теперь это само по себе не вызывает беспокойства, поскольку я верю в полномочия Кассандры и ее способность в конечном итоге получить данные в нужном месте. Меня очень беспокоит то, что мой стол с точно 5 000 строк теперь больше не имеют 5000 строк в любом из трех моих регионов.

# From ap-southeast-1 

cqlsh> CONSISTENCY ONE; 
Consistency level set to ONE. 

cqlsh> select count(*) from health_check_data_consistency; 

count 
------- 
    3891 

cqlsh> CONSISTENCY LOCAL_QUORUM; 
Consistency level set to LOCAL_QUORUM. 

cqlsh> select count(*) from health_check_data_consistency; 

count 
------- 
    4633 


# From eu-west-1 

cqlsh> CONSISTENCY ONE; 
Consistency level set to ONE. 

cqlsh> select count(*) from health_check_data_consistency; 

count 
------- 
    1975 

cqlsh> CONSISTENCY LOCAL_QUORUM; 
Consistency level set to LOCAL_QUORUM. 

cqlsh> select count(*) from health_check_data_consistency; 

count 
------- 
    4209 


# From us-east-1 

cqlsh> CONSISTENCY ONE; 
Consistency level set to ONE. 

cqlsh> select count(*) from health_check_data_consistency; 

count 
------- 
    4435 

cqlsh> CONSISTENCY LOCAL_QUORUM; 
Consistency level set to LOCAL_QUORUM. 

cqlsh> select count(*) from health_check_data_consistency; 

count 
------- 
    4870 

Так серьезно, что здесь происходит? Вспомним:

  • мой коэффициент репликации - 'ap-southeast-1-A': '2', 'eu-west-1-A': '2', 'us-east-1-A': '2', поэтому каждый регион должен быть в состоянии удовлетворить запрос в полном объеме.
  • Приобретение новых экземпляров не должно приводить к потере данных, но, видимо, мы делаем это даже с LOCAL_QUORUM
  • В каждом регионе есть другой вид данных, но я не представил никаких новых данных, только новые серверы, которые затем загружают автоматически.

Итак, тогда я подумал, почему бы не сделать запрос QUORUM во всем многопользовательском кластере. К сожалению, это не удается полностью:

cqlsh> CONSISTENCY QUORUM; 
Consistency level set to QUORUM. 

cqlsh> select count(*) from health_check_data_consistency; 
OperationTimedOut: errors={}, last_host=172.17.0.2 

Затем я повернулся TRACING ON; и тоже не получилось. Все, что я вижу в журналах, следующее:

INFO [SlabPoolCleaner] 2016-03-03 19:16:16,616 ColumnFamilyStore.java:1197 - Flushing largest CFS(Keyspace='system_traces', ColumnFamily='events') to free up room. Used total: 0.33/0.00, live: 0.33/0.00, flushing: 0.00/0.00, this: 0.02/0.02 
INFO [SlabPoolCleaner] 2016-03-03 19:16:16,617 ColumnFamilyStore.java:905 - Enqueuing flush of events: 5624218 (2%) on-heap, 0 (0%) off-heap 
INFO [MemtableFlushWriter:1126] 2016-03-03 19:16:16,617 Memtable.java:347 - Writing [email protected](1.102MiB serialized bytes, 25630 ops, 2%/0% of on/off-heap limit) 
INFO [MemtableFlushWriter:1126] 2016-03-03 19:16:16,821 Memtable.java:382 - Completed flushing /var/lib/cassandra/data/system_traces/events/system_traces-events-tmp-ka-3-Data.db (298.327KiB) for commitlog position ReplayPosition(segmentId=1456854950580, position=28100666 
) 
INFO [ScheduledTasks:1] 2016-03-03 19:16:21,210 MessagingService.java:929 - _TRACE messages were dropped in last 5000 ms: 212 for internal timeout and 0 for cross node timeout 

Это происходит на каждом сервере, на котором я запускаю запрос.

Проверка кластера, кажется, все в синхронизации

$ nodetool describecluster; 
Cluster Information: 
    Name: Ably 
    Snitch: org.apache.cassandra.locator.DynamicEndpointSnitch 
    Partitioner: org.apache.cassandra.dht.Murmur3Partitioner 
    Schema versions: 
      51e57d47-8870-31ca-a2cd-3d854e449687: [54.78.xxx.xxx, 54.152.xxx.xxx, 54.254.xxx.xxx, 54.255.xxx.xxx, 54.195.xxx.xxx, 54.194.xxx.xxx, 54.225.xxx.xxx, 52.91.xxx.xxx, 54.229.xxx.xxx, 54.169.xxx.xxx, 54.224.xxx.xxx, 54.255.xxx.xxx] 

ДАЛЕЕ UPDATE 1 час позже

Кто-то предположил, что, возможно, это был просто вниз в диапазоне запросов не работает, как ожидалось. Таким образом, я написал простой скрипт, запрошенный для каждой из 5k строк в отдельности (у них есть диапазон идентификаторов 1-> 5000). К сожалению, результаты, как я боялся, у меня отсутствуют данные. Я пробовал это с LOCAL_ONE, LOCAL_QUORUM и событием QUORUM.

ruby> (1..5000).each { |id| put "#{id} missing" if session.execute("select id from health_check_data_consistency where id = #{id}", consistency: :local_quorum).length == 0 } 
19 missing, 61 missing, 84 missing, 153 missing, 157 missing, 178 missing, 248 missing, 258 missing, 323 missing, 354 missing, 385 missing, 516 missing, 538 missing, 676 missing, 708 missing, 727 missing, 731 missing, 761 missing, 863 missing, 956 missing, 1006 missing, 1102 missing, 1121 missing, 1161 missing, 1369 missing, 1407 missing, 1412 missing, 1500 missing, 1529 missing, 1597 missing, 1861 missing, 1907 missing, 2005 missing, 2168 missing, 2207 missing, 2210 missing, 2275 missing, 2281 missing, 2379 missing, 2410 missing, 2469 missing, 2672 missing, 2726 missing, 2757 missing, 2815 missing, 2877 missing, 2967 missing, 3049 missing, 3070 missing, 3123 missing, 3161 missing, 3235 missing, 3343 missing, 3529 missing, 3533 missing, 3830 missing, 4016 missing, 4030 missing, 4084 missing, 4118 missing, 4217 missing, 4225 missing, 4260 missing, 4292 missing, 4313 missing, 4337 missing, 4399 missing, 4596 missing, 4632 missing, 4709 missing, 4786 missing, 4886 missing, 4934 missing, 4938 missing, 4942 missing, 5000 missing 

Как вы можете видеть выше, это означает, что у меня примерно 1,5% моих данных больше не доступны.

Так что я в тупике. Мне действительно нужен какой-то совет, потому что у меня явно было впечатление, что Кассандра была специально разработана для того, чтобы справляться с горизонтальным увеличением по требованию. Любая помощь очень ценится.

ответ

0

Что касается собственности. Это основано на владении токеном, а не фактических данных. Таким образом, заявленная собственность в каждом случае выглядит корректно независимо от объема данных на каждом узле.

Во-вторых, вы не можете гарантировать согласованность с двумя узлами (если вы не жертвуете доступностью и не используете CL = ALL). QUORUM = большинство. Вам нужно, по крайней мере, три узла на постоянный ток, чтобы действительно получить кворум. Если согласованность важна для развертывания трех узлов на постоянный ток и чтение и запись QUORUM.

Счетчик SELECT (*) через DC отправляется в режим ожидания. Вероятно, существует несколько сотен мс латентности между вашими и цифровыми центрами. Плюс выберите count (*) - это дорогостоящая операция.

Когда вы делаете QUORUM, прочитайте, что Cassandra собирается исправить непоследовательные данные с помощью исправления для чтения. Вот почему ваши подсчеты точны после запуска запроса в кворуме.

Все, что было сказано, похоже, что у вас проблема с загрузкой, потому что новые узлы не получают все данные. Сначала я запустил ремонт на всех узлах и удостоверился, что у них у всех 5000 записей после этого. Это даст вам понять, что потоковая передача не нарушена. Затем повторите замену узла так же, как и раньше. На этот раз монитор с nodetool netstats и смотреть журналы. Сообщение ничего странного. И не забывайте, что вам нужно запустить очистку nodetool, чтобы удалить данные из старых узлов.

Можете ли вы описать конфигурацию вашего оборудования (ОЗУ, ЦП, диск и т. Д.)?

+0

Спасибо за ответ Iain. 'Вы не можете гарантировать согласованность с двумя узлами'. Но кворум в C * docs определяется как' (sum_of_replication_factors/2) + 1'. Итак, если в одном DC у нас есть 2 узла с RF 2, то это 2/2 + 1, что равно 2. Почему мы не можем гарантировать согласованность? 'Когда вы читаете QUORUM, C * собирается исправить непоследовательные данные с помощью read repair' - Не так сейчас, к сожалению, отсутствует 56 из 5000 строк. Выполняется однострочный запрос с CL ALL. Теперь отремонтировать узел, довольно обремененный серверами и очень медленный (4 часа на каждое пространство ключей до 8 ключей), будет обновляться после завершения. –

+0

Iain, в отношении вашего комментария 'Что касается собственности. Это основано на владении токеном, а не фактических данных. Таким образом, заявленное право собственности в каждом случае выглядит правильно, независимо от объема данных на каждом узле. С тех пор я завершил полный ремонт кластера, и теперь, когда он завершен, я все еще вижу ОГРОМНЫЙ дисбаланс в нагрузке, то есть 8 ГБ на старом сервере, 500 МБ на новом сервере. Как Cassandra в конечном итоге убедитесь, что данные действительно правильно распределены в соответствии с принадлежностью маркера? Без правильной передачи данных существует серьезный риск потери данных. –

0

Что я должен был сказать, вы не можете гарантировать согласованность и доступность. Поскольку ваш запрос кворума по существу является запросом ALL. Единственный способ запроса, когда один из узлов вниз, - это снизить CL. И это не приведет к исправлению чтения, если данные на доступном узле несовместимы.

После выполнения ремонта вам также необходимо запустить очистку на старых узлах, чтобы удалить данные, которые они больше не имеют. Кроме того, ремонт не удаляет данные удаленных/TTLd до истечения периода gc_grace_seconds. Поэтому, если у вас есть что-то из этого, он будет придерживаться, по крайней мере, gc_grace_seconds.

Вы нашли что-нибудь в бревнах? Можете ли вы поделиться своей конфигурацией?