Странное поведение при обновлении строки Cassandra

Я использую pyspark и pyspark-cassandra.

Я заметил такое поведение в нескольких версиях Cassandra (3.0.x и 3.6.x) с использованием COPY, sstableloader, а теперь и saveToCassandra в pyspark.

у меня следующая схема

CREATE TABLE test (
    id int,
    time timestamp,
    a int,
    b int,
    c int,
    PRIMARY KEY ((id), time)
) WITH CLUSTERING ORDER BY (time DESC);

и следующие данные

(1, datetime.datetime(2015, 3, 1, 0, 18, 18, tzinfo=<UTC>), 1, 0, 0)
(1, datetime.datetime(2015, 3, 1, 0, 19, 12, tzinfo=<UTC>), 0, 1, 0)
(1, datetime.datetime(2015, 3, 1, 0, 22, 59, tzinfo=<UTC>), 1, 0, 0)
(1, datetime.datetime(2015, 3, 1, 0, 23, 52, tzinfo=<UTC>), 0, 1, 0)
(1, datetime.datetime(2015, 3, 1, 0, 32,  2, tzinfo=<UTC>), 1, 1, 0)
(1, datetime.datetime(2015, 3, 1, 0, 32,  8, tzinfo=<UTC>), 0, 2, 0)
(1, datetime.datetime(2015, 3, 1, 0, 43, 30, tzinfo=<UTC>), 1, 1, 0)
(1, datetime.datetime(2015, 3, 1, 0, 44, 12, tzinfo=<UTC>), 0, 2, 0)
(1, datetime.datetime(2015, 3, 1, 0, 48, 49, tzinfo=<UTC>), 1, 1, 0)
(1, datetime.datetime(2015, 3, 1, 0, 49,  7, tzinfo=<UTC>), 0, 2, 0)
(1, datetime.datetime(2015, 3, 1, 0, 50,  5, tzinfo=<UTC>), 1, 1, 0)
(1, datetime.datetime(2015, 3, 1, 0, 50, 53, tzinfo=<UTC>), 0, 2, 0)
(1, datetime.datetime(2015, 3, 1, 0, 51, 53, tzinfo=<UTC>), 1, 1, 0)
(1, datetime.datetime(2015, 3, 1, 0, 51, 59, tzinfo=<UTC>), 0, 2, 0)
(1, datetime.datetime(2015, 3, 1, 0, 54, 35, tzinfo=<UTC>), 1, 1, 0)
(1, datetime.datetime(2015, 3, 1, 0, 55, 28, tzinfo=<UTC>), 0, 2, 0)
(1, datetime.datetime(2015, 3, 1, 0, 55, 55, tzinfo=<UTC>), 1, 2, 0)
(1, datetime.datetime(2015, 3, 1, 0, 56, 24, tzinfo=<UTC>), 0, 3, 0)
(1, datetime.datetime(2015, 3, 1, 1, 11, 14, tzinfo=<UTC>), 1, 2, 0)
(1, datetime.datetime(2015, 3, 1, 1, 11, 17, tzinfo=<UTC>), 2, 1, 0)
(1, datetime.datetime(2015, 3, 1, 1, 12,  8, tzinfo=<UTC>), 1, 2, 0)
(1, datetime.datetime(2015, 3, 1, 1, 12, 10, tzinfo=<UTC>), 0, 3, 0)
(1, datetime.datetime(2015, 3, 1, 1, 17, 43, tzinfo=<UTC>), 1, 2, 0)
(1, datetime.datetime(2015, 3, 1, 1, 17, 49, tzinfo=<UTC>), 0, 3, 0)
(1, datetime.datetime(2015, 3, 1, 1, 24, 12, tzinfo=<UTC>), 1, 2, 0)
(1, datetime.datetime(2015, 3, 1, 1, 24, 18, tzinfo=<UTC>), 2, 1, 0)
(1, datetime.datetime(2015, 3, 1, 1, 24, 18, tzinfo=<UTC>), 1, 2, 0)
(1, datetime.datetime(2015, 3, 1, 1, 24, 24, tzinfo=<UTC>), 2, 1, 0)

Ближе к концу данных есть две строки с одинаковой отметкой времени.

(1, datetime.datetime(2015, 3, 1, 1, 24, 18, tzinfo=<UTC>), 2, 1, 0)
(1, datetime.datetime(2015, 3, 1, 1, 24, 18, tzinfo=<UTC>), 1, 2, 0)

Насколько я понимаю, когда я сохраняю в Cassandra, один из них «выиграет» - будет только одна строка.

После написания Кассандре с помощью

rdd.saveToCassandra(keyspace, table, ['id', 'time', 'a', 'b', 'c'])

Кажется, что ни один из рядов не выиграл. Скорее, ряды как бы «слились».

   1 |  2015-03-01 01:17:43+0000 |        1 |        2 |        0
   1 |  2015-03-01 01:17:49+0000 |        0 |        3 |        0
   1 |  2015-03-01 01:24:12+0000 |        1 |        2 |        0
   1 |  2015-03-01 01:24:18+0000 |        2 |        2 |        0
   1 |  2015-03-01 01:24:24+0000 |        2 |        1 |        0

Вместо 2015-03-01 01:24:18+0000, содержащего (1, 2, 0) или (2, 1, 0), он содержит (2, 2, 0).

Что здесь происходит? Я не могу на всю жизнь понять, что такое поведение вызвано.


person dacox    schedule 12.07.2016    source источник


Ответы (1)


Это малоизвестный эффект, возникающий при объединении данных в пакеты. При пакетной записи всем вставкам в пакете назначается одна и та же метка времени. Далее, если две записи выполняются с точно одной и той же отметкой времени, то применяется специальное правило слияния, поскольку не было "последней" записи. Соединитель Spark Cassandra по умолчанию использует пакеты внутри раздела, поэтому это, скорее всего, произойдет, если у вас есть такое затирание значений.

Поведение с двумя идентичными отметками времени записи представляет собой слияние на основе значения Больше.

Данная таблица (ключ, а, б)

Batch
Insert "foo", 2, 1
Insert "foo", 1, 2
End batch

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

"foo", 2, 2
person RussS    schedule 13.07.2016
comment
Спасибо, я подозревал, что что-то подобное происходит, но не мог найти никакой информации об этом. Как на практике люди с этим справляются? Просто убедитесь, что у вас есть исторические данные с точностью до миллисекунды? - person dacox; 13.07.2016
comment
Ну, есть несколько вещей, которые вы можете сделать в зависимости от вашей цели. В большинстве случаев пользователи просто пытаются гарантировать, что в одном пакете не будет повторяющихся первичных ключей. Если вы хотите сохранить обе записи в C *, вам нужно будет как-то их различать (например, с миллисекундами или TimeUUID). Некоторые пользователи добавляют разные временные метки для принудительного упорядочения (т. Е. Если каждая вставка имеет восходящий порядок, они будут применяться в этом заказ.) На самом деле у вас нет этой опции, так как ваши партии создаются автоматически. Это также теряет дубликаты. - person RussS; 14.07.2016