2016-12-31 2 views
1

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

Например, предположим, что у меня есть отношения «многие ко многим» между актерами и фанатами. Фанат может поддержать многих актеров, и у актера есть много поклонников. Я делаю несколько таблиц, чтобы поддержать мои запросы

CREATE TABLE fans (
    fan_id uuid, 
    fan_attr_1 int, 
    fan_attr_2 int 
    PRIMARY KEY ((fan_id)) 
) 

CREATE TABLE actors (
    actor_id uuid, 
    actor_attr_1 int, 
    actor_attr_2 int 
    PRIMARY KEY ((actor_id)) 
) 

CREATE TABLE actors_by_fan (
    fan_id uuid, 
    actor_id uuid, 
    actor_attr_1 int, 
    actor_attr_2 int 
    PRIMARY KEY (fan_id, actor_id) 
) 

CREATE TABLE fans_by_actor (
    actor_id uuid, 
    fan_id uuid, 
    fan_attr_1 int, 
    fan_attr_2 int 
    PRIMARY KEY (actor_id, fan_id) 
) 

Допустим, я фанат, и я нахожусь на моей странице настроек, и я хочу изменить мой fan_attr_1 другого значения.

В таблице fans я могу точно обновить свой атрибут, так как приложение знает мой fan_id и может использовать этот ключ.

Однако я не могу изменить свой fan_attr_1 на fans_by_actor без предварительного запроса для actor_ids, привязанного к вентилятору.

Эта проблема возникает в любое время, когда вы хотите обновить любой атрибут fans или actors.

Я пробовал искать онлайн для людей, испытывающих подобные проблемы, но я не мог их найти. Например, в курсе Data Dataing Datastax они используют примеры с актерами и видеороликами во многих отношениях, где у них есть таблицы actors_by_video и videos_by_actor. Курс, как и другие онлайн-ресурсы, с которыми я консультировался, обсуждал таблицы моделирования после запросов, но не вникнул в то, как сохранить целостность данных. В таблице actors_by_video, что произойдет, если я хочу изменить атрибут актера? Не нужно было бы проходить через каждую строку actors_by_video, чтобы найти разделы, содержащие актера, и обновить атрибут? Это звучит очень неэффективно. Другой вариант заключается в том, чтобы искать идентификатор видео заранее, но я читал в другом месте, которое читает до того, как записи являются антипаттером в Кассандре.

Каким будет наилучший подход для решения этой проблемы либо с точки зрения моделирования данных, либо с точки зрения CQL?

EDIT: - Фиксированные приговаривают окурки - Добавлен контекст и предварительное исследование

+0

Какие вопросы вы собираетесь сделать?Вы моделируете свои данные вокруг запросов, а не вокруг их отношений (это не реляционный db). Мог бы проверить https://academy.datastax.com/resources/ds220-data-modeling для некоторых уроков по моделированию данных в cassandra –

+0

Да, я действительно взял курс, прежде чем спрашивать здесь, но курс, похоже, не отвечает на вопросы самих себя. В своем примере KillrVideo они используют как «video_by_actor», так и «act_by_videos», что является аналогичной парадигмой, описанной выше. Однако они никогда не обсуждали, как эти таблицы должны поддерживаться, если атрибут актера или изменение атрибута видео –

ответ

0

Моделирование данных

Cassandra не является реляционной базы данных и существуют определенные основные правила должны быть выполнены на DataModeling , на высоком уровне для нашей модели данных необходимо следовать следующим целям.

1) Распространение данных равномерно вокруг кластера

2) сводят к минимуму количество разделов чтения

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

Обратите внимание, что существует ограничение размера на имена и значения столбцов. Максимальный размер ключа столбца (и строки строки) составляет 64 КБ. Максимальный размер столбца составляет 2 ГБ. Но из-за отсутствия потоковой передачи, и вся ценность извлекается в памяти кучи по запросу, ограничивает размер всего лишь несколькими мегабайтами.

Дополнительная информация:

http://www.datastax.com/dev/blog/basic-rules-of-cassandra-data-modeling

http://www.ebaytechblog.com/2012/07/16/cassandra-data-modeling-best-practices-part-1/

http://www.ebaytechblog.com/2012/08/14/cassandra-data-modeling-best-practices-part-2/

https://docs.datastax.com/en/cql/3.1/cql/cql_reference/refLimits.html

CQL

Поддержание согласованности между таблицами может быть выполнено с использованием Batch или Materialized Views. Материализованные представления доступна с версии 3.0

Пожалуйста, см

How to ensure data consistency in Cassandra on different tables?

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

Надеюсь, что это поможет!

+0

Я все еще не вижу света здесь, может быть, конкретный пример поможет. Предположим, вы моделируете пример, описанный выше. Как бы вы структурировали таблицу для поддержки запросов? –

0

материализованных представлений, вероятно, лучший выбор:

CREATE MATERIALIZED VIEW actors_by_fan 
AS SELECT fan_id, actor_id, actor_attr_1, actor_attr_2 
FROM fans 
PRIMARY KEY (fan_id, actor_id); 

CREATE MATERIALIZED VIEW fans_by_actor 
AS SELECT actor_id, fan_id, fan_attr_1, fan_attr_2 
FROM actors 
PRIMARY KEY (actor_id, fan_id); 

В версиях до 3.0, создавать вторичные индексы и оценить, если их производительность является приемлемым. Позже, после обновления до 3.x, просто снимите вторичные индексы и создайте материализованные представления.

+0

Спасибо за интересный подход. Однако мы используем более старую версию Cassandra (2.2.7), которая не поддерживает материализованные представления:/Я не могу себе представить, что я единственный человек, столкнувшийся с этой проблемой, интересно, как другие SWE решают эту проблему. Вторичные индексы будут вариантом, но он не подходит для данных с высокой мощностью. –

0

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

Поскольку вы не можете использовать материализованные представления для того, чтобы обновить fan_attr_1 на ваших данных вам необходимо:

  1. Обновление fan таблицы путем выдачи UPDATE fan ... WHERE fan_id = xxx.
  2. Выделить все actor_id s из actors_by_fan, выпустив SELECT actor_id ... WHERE fan_id = xxx.
  3. Обновление всех соответствующих строк в таблице fans_by_actor путем выдачи UPDATE fans_by_actor ... WHERE actor_id IN (...) или, альтернативно, цикла по actor_id с и запуска каждого асинхронного обновления.

До тех пор, пока у вас есть небольшое количество actor_id в шаге 2, скажем, менее 20, вы можете сгруппировать все запросы и поддерживать сильную согласованность между таблицами, запуская их в одном BATCH. В противном случае вам нужно гарантировать согласованность между таблицами.

Это может быть так же неэффективно, как кажется, но я не думаю, что есть другие более умные решения. Кстати, вы выдаете один прочитанный (шаг 2) и несколько записей (шаги 1 и 3). Это не конец света, особенно если вы не меняете атрибуты , так что часто (например, каждые 10 миллисекунд).

Смежные вопросы