MySQL в Redis - импорт и модель

Я думаю использовать Redis для кеширования некоторых снимков пользовательских данных, чтобы ускорить доступ к этим данным. (одна из причин заключается в том, что мои таблицы MySQL страдают от конфликтов блокировки), и я ищу лучший способ импортировать за один шаг такую ​​таблицу (которая может содержать от нескольких записей до миллионов записей):

mysql> select * from mytable where snapshot = 1133;
+------+--------------------------+----------------+-------------------+-----------+-----------+
| id   | email                    | name           | surname           | operation | snapshot  |
+------+--------------------------+----------------+-------------------+-----------+-----------+
| 2989 | [email protected] | fake-name-2989 | fake-surname-2989 |         2 |      1133 |
| 2990 | [email protected] | fake-name-2990 | fake-surname-2990 |        10 |      1133 |
| 2992 | [email protected] | fake-name-2992 | fake-surname-2992 |         5 |      1133 |
| 2993 | [email protected] | fake-name-2993 | fake-surname-2993 |         5 |      1133 |
| 2994 | [email protected] | fake-name-2994 | fake-surname-2994 |         9 |      1133 |
| 2995 | [email protected] | fake-name-2995 | fake-surname-2995 |         7 |      1133 |
| 2996 | [email protected] | fake-name-2996 | fake-surname-2996 |         1 |      1133 |
+------+--------------------------+----------------+-------------------+-----------+-----------+

в хранилище ключей и значений Redis.

У меня может быть много «снимков» для загрузки в Redis, и базовый шаблон доступа (синтаксис, подобный SQL)

  • select * from mytable where snapshot = ? and id = ?

эти снимки также могут поступать из других таблиц, поэтому "глобальный уникальный идентификатор для каждого снимка" - это столбец snapshot, например:

mysql> select * from my_other_table where snapshot = 1134;
+------+--------------------------+----------------+-------------------+-----------+-----------+
| id   | email                    | name           | surname           | operation | snapshot  |
+------+--------------------------+----------------+-------------------+-----------+-----------+
| 2989 | [email protected] | fake-name-2989 | fake-surname-2989 |         1 |      1134 |
| 2990 | [email protected] | fake-name-2990 | fake-surname-2990 |         8 |      1134 |
| 2552 | [email protected] | fake-name-2552 | fake-surname-2552 |         5 |      1134 |
+------+--------------------------+----------------+-------------------+-----------+-----------+

Загруженные снимки в Redis никогда не меняются, они доступны только в течение недели по TTL

  • Есть ли способ загрузить за один шаг такие данные (строки и столбцы) в redis, комбинируя redis-cli --pipe и HMSET?

  • Какую модель лучше всего использовать в Redis для хранения / получения этих данных (думая о шаблоне доступа)?

Я нашел redis-cli --pipe Redis Mass Insertion (а также MySQL to Redis за один шаг), но я не могу найти лучшего способ выполнить мои требования (загрузить из mysql за один шаг все строки / столбцы, лучшая модель redis для этого) с помощью HMSET

заранее спасибо

Кристиан.


person Cristian Porta    schedule 25.09.2013    source источник
comment
Снимки добавляются по ходу работы, а старые снимки никогда не меняются, или каков шаблон обновления?   -  person Joachim Isaksson    schedule 25.09.2013
comment
@JoachimIsaksson снимки никогда не меняются, им нужен только TTL (например, 1 неделя), после чего данные можно отбросить.   -  person Cristian Porta    schedule 25.09.2013
comment
Затем (будучи никоим образом не экспертом, а просто пользователем), я бы добавил хэш для каждого снимка, используя id в качестве ключа. Если остальные данные никогда не запрашиваются, вы можете просто использовать кодировку данных JSON в качестве значения.   -  person Joachim Isaksson    schedule 25.09.2013
comment
@CristianPorta Я предложил модель данных, скажите, что вы думаете!   -  person FGRibreau    schedule 30.09.2013


Ответы (1)


Модель

Чтобы иметь возможность запрашивать данные из Redis так же, как:

select * from mytable where snapshot = ?
select * from mytable where id = ?

Вам понадобится модель ниже.

Примечание: select * from mytable where snapshot = ? and id = ? здесь не имеет большого смысла, поскольку это то же самое, что и select * from mytable where id = ?.

Тип ключа и название

[Key Type] [Key name pattern]
HASH       d:{id}
ZSET       d:ByInsertionDate
SET        d:BySnapshot:{id}

Примечание. Я использовал d: в качестве пространства имен, но вы можете переименовать его, указав имя своей модели домена.

Вставка данных

Вставьте новую строку из Mysql в Redis:

hmset d:2989 id 2989 email [email protected] name fake-name-2989 ... snapshot 1134
zadd d:ByInsertionDate {current_timestamp} d:2989
sadd d:BySnapshot:1134 d:2989

Другой пример:

hmset d:2990 id 2990 email [email protected] name fake-name-2990 ... snapshot 1134
zadd d:ByInsertionDate {current_timestamp} d:2990
sadd d:BySnapshot:1134 d:2990

Cron

Вот алгоритм, который необходимо запускать каждый день или неделю в зависимости от ваших требований:

for key_name in redis(ZREVRANGEBYSCORE d:ByInsertionDate -inf {timestamp_one_week_ago})

 // retrieve the snapshot id from d:{id}
 val snapshot_id = redis(hget {key_name} snapshot)

 // remove the hash (d:{id})
 redis(del key_name)

 // remove the hash entry from the set
 redis(srem d:BySnapshot:{snapshot_id} {key_name})

// clean the zset from expired keys
redis(zremrangebyscore d:ByInsertionDate -inf {timestamp_one_week_ago})

использование

select * from my_other_table where snapshot = 1134; будет либо:

{snapshot_id} = 1134
for key_name in redis(smembers d:BySnapshot:{snapshot_id})
  print(redis(hgetall {keyname}))

или напишите lua-скрипт, чтобы сделать это прямо на стороне Redis. Наконец-то:

select * from my_other_table where id = 2989; будет:

{id} = 2989
print(redis(hgetall d:{id}))

Импортировать

Эта часть довольно проста, просто прочтите таблицу и следуйте приведенной выше модели. В зависимости от ваших требований вы можете захотеть импортировать все (или часть) свои данные с помощью ежечасного / дневного / еженедельного cron.

person FGRibreau    schedule 29.09.2013