2017-01-27 3 views
0

Я регулярно получать два типа наборов данных:Cassandra подход РСУБД вложенных вставок

сети потоков, тысячи в секунду:

{ 
    'stamp' : '2017-01-19 01:37:22' 
    'host' : '192.168.2.6', 
    'ip_src' : '10.29.78.3', 
    'ip_dst' : '8.8.4.4', 
    'iface_in' : 19, 
    'iface_out' : 20, 
    (... etc ..) 
} 

и интерфейс таблиц, каждый час:

[ 
    { 
     'stamp' : '2017-01-19 03:00:00' 
     'host' : '192.168.2.6', 
     'iface_id' : 19 
     'iface_name' : 'Fa0/0' 
    },{ 
     'stamp' : '2017-01-19 03:00:00' 
     'host' : '192.168.2.6', 
     'iface_id' : 20 
     'iface_name' : 'Fa0/1' 
    },{ 
     'stamp' : '2017-01-19 03:00:00' 
     'host' : '192.168.157.38', 
     'iface_id' : 20 
     'iface_name' : 'Gi0/3' 
    } 
] 

Я хочу вставить те потоки в Cassandra с именами интерфейсов, а не идентификаторами, на основе последнего совпадающего значения host/iface_id. Я не могу полагаться на решение только для памяти, иначе я могу потерять до одного часа потоков каждый раз, когда я перезапущу приложение.

Что я имел в виду, это использовать две таблицы Кассандры: одну, которая содержит потоки, и ту, которая содержит последнюю таблицу хоста/iface_id. Затем, получая поток, я использовал бы эти данные для правильного заполнения имени интерфейса.

В идеале я хотел бы, чтобы Cassandra позаботилась об этом. На мой взгляд, это кажется более эффективным, чем вытягивание имен интерфейсов со стороны приложения каждый раз.

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

Вставка данных в таблицу интерфейсов и сохранение только последней версии довольно тривиальна, но я не могу обдумать часть раздела «Вставка имени интерфейса в потоковой записи». В традиционной RDBMS я бы использовал вложенный запрос, но они, похоже, не существуют в Кассандре.

ответ

0

Чтение вашего вопроса, я могу надеяться, что данные, полученные по часам в таблице интерфейсов, не слишком велики. Поэтому мы можем хранить эти данные (одну строку) в памяти, а также в базе данных cassandra. За каждый час данные в памяти будут обновляться, а также новые, вставленные в базу данных. Мы можем сохранить данные интерфейса с ниже определения таблицы -

 create table interface_by_hour(
     year int, 
     month int, 
     day int, 
     hour int, 
     data text, -- enitre json string for one hour interface data. 
     primary key((year,month,day,hour))); 

Несколько заявлений вставки -

insert into interface_by_hour (year,month,day,hour,data) values (2017,1,27,23,'{complete json.........}'); 
    insert into interface_by_hour (year,month,day,hour,data) values (2017,1,27,00,'{complete json.........}'); 
    insert into interface_by_hour (year,month,day,hour,data) values (2017,1,28,1,'{complete json.........}'); 

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

cqlsh:mykeyspace> select * from interface_by_hour where year=2017 and month=1 and day=27 and hour=0; 

    year | month | day | hour | data 
    ------+-------+-----+------+-------------------------- 
    2017 |  1 | 27 | 0 | {complete json.........} 

Сейчас идет поток данных -

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

create table flow(
    iface_name text, 
    createdon bingint, -- time stamp in milliseconds. 
    host text, -----this is optionl, if you want dont use it as column. 
    flowdata text, -- entire json string 
    primarykey(iface_name,createdon,host)); 

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

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

надеюсь, что это поможет.

+1

Мне нравится подход к хранению почасового объекта JSON непосредственно для интерфейсов. Это также позволяет «оглянуться назад», если что-то пошло не так, когда вставляете поток, а не используете только последнее значение. – YaHaBoHo

+0

просто учтите, что данные json 10MB вредны для cassandra, не просто сохраняйте их необработанными, используйте структуры или сохраняйте их на несколько разных кусков, и это будет o.k. Обычно они не идут намного больше 10 или 100 К за кусок, а также используют время для жизни, потому что слишком много в истории может стоить вам много места. –

0

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

create table interface(
    iface_name text primary key, 
    iface_id int, 
    host text, 
    stamp timestamp 
); 

insert into interface(iface_name, iface_id, host, stamp) values ('Fa0/0', 19, '192.168.2.6', '2017-01-19 03:00:00'); 
insert into interface(iface_name, iface_id, host, stamp) values ('Fa0/1', 20, '192.168.2.6', '2017-01-19 03:00:00'); 
insert into interface(iface_name, iface_id, host, stamp) values ('Gi0/3', 20, '192.168.157.38', '2017-01-19 03:00:00'); 

обычно это antipatern с Кассандрой:

cqlsh:test> select * from interface; 

iface_name | host   | iface_id | stamp 
------------+----------------+----------+--------------------------------- 
     Fa0/0 | 192.168.2.6 |  19 | 2017-01-19 02:00:00.000000+0000 
     Gi0/3 | 192.168.157.38 |  20 | 2017-01-19 02:00:00.000000+0000 
     Fa0/1 | 192.168.2.6 |  20 | 2017-01-19 02:00:00.000000+0000 

Но, насколько я вижу, что вы не имеете, что многие интерфейсы

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

Я бы просто сохранил эту таблицу в памяти, а затем обогатил данные по мере их поступления. Если есть обновления, обновите кеш памяти ... но также поместите записи в cassandra. Если что-то не удается, просто восстановите его из таблицы интерфейса и продолжите.

в основном ваша информация потока будет затем стать

{ 
    'stamp' : '2017-01-19 01:37:22' 
    'host' : '192.168.2.6', 
    'ip_src' : '10.29.78.3', 
    'ip_dst' : '8.8.4.4', 
    'iface_in' : 19, 
    'iface_out' : 20, 

    'iface_name' : 'key put from in memory cache', 
} 

Это, как вы получите Bigest производительность Теперь экономия потоков только данных временных рядов, то, примите во внимание, что вы ударяете кластер с тысячами в секунду, и что, когда вы будете парифицировать по времени, вы должны получить не менее 7000, если не больше столбцов каждую секунду (с моделью , которую я предлагаю здесь) обычно вам нужно иметь до 100 000 столбцов в одном разделе, который сказал бы, что ваш раздел переполнен идеальных размера жгуты 20 секунд или даже меньше, так что я бы даже предложили использовать случайные ведра (при вставке просто использовать некоторое число в заданном диапазоне давайте скажем, 10):

create table flow(
    time_with_minute text, 
    artificial_bucket int, 
    stamp timeuuid, 
    host text, 
    ip_src text, 
    ip_dst text, 
    iface_in int, 
    iface_out int, 
    iface_name text, 
    primary key((time_with_minute, artificial_bucket), stamp) 
); 

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

вставки тогда что-то вроде:

insert into flow(time_with_minute, artificial_bucket, stamp, host, ip_src, ip_dst, iface_in, iface_out, iface_name) 
    values ('2017-01-19 01:37', 1, now(), '192.168.2.6', '10.29.78.3', '8.8.4.4', 19, 20, 'Fa0/0'); 

Я сейчас используется только для примера, используйте https://github.com/apache/cassandra/blob/cassandra-2.1/src/java/org/apache/cassandra/utils/UUIDGen.java для генерации timeuuid со временем, когда вы вставили поток. Также я вставил 1 в искусственное ведро, здесь вы вставляете случайное число с диапазоном, скажем, как минимум 0-10. Некоторые люди, в зависимости от нагрузки, вставляют несколько случайных ведер, даже 60 или более. Все зависит от того, насколько тяжелыми являются записи. Если вы просто поместите его в минуту каждую минуту, группа узлов внутри кластера будет горячей, и это будет переключаться. Наличие горячих узлов обычно не является хорошей идеей.

С помощью cassandra вы пишете необходимую информацию сразу, вы не делаете любых подключений во время записи или чего-то подобного.Храните данные в памяти, которые вам нужны, чтобы отпечатал данные с необходимой информацией и просто вставлял без денормализации.

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

+0

Я также пришел к такому выводу, данные интерфейса действительно не такие большие (при условии, что 5000 устройств по 32 интерфейса каждый, это должно составлять +/- 10 МБ каждый час) и может храниться в памяти. – YaHaBoHo

+0

Если это 10 МБ, это полностью кандидат в кеш-память с резервным копированием в cassandra, если что-то пойдет не так :) Я бы не посоветовал подход gunwant с 10 МБ данных в одном разделе, потому что выборка 10 МБ из одного раздела займет много времени (несколько секунд) ... но если это загрузка после сбоя, возможно, это будет нормально После того, как у меня было около 300 КБ данных в разделе, и это действительно заняло много времени, чтобы получить его. –

+0

Теперь я думаю об использовании встроенной базы данных памяти sqlite3. – YaHaBoHo

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