将 Redis 数据同步到 MySQL 的最佳策略是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23080557/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 20:26:08  来源:igfitidea点击:

What's the best strategy to sync Redis data to MySQL?

mysqldatabasearchitectureredis

提问by pengdu

  1. The use case is to use Redis to be local cache of MySQL
  2. The data format in MySQL is: a single primary key and several other fields. There will not be queries cross table of db
  3. Redis key is primary key in MySQL, and value is hash containing other fields in MySQL
  4. When power off, less than one minute data lose is acceptable.
  1. 用例是使用Redis作为MySQL的本地缓存
  2. MySQL 中的数据格式是:一个主键和几个其他字段。不会有db的跨表查询
  3. Redis key 是 MySQL 中的主键,value 是包含 MySQL 中其他字段的 hash
  4. 断电时,小于一分钟的数据丢失是可以接受的。

My solution is:

我的解决办法是:

  1. Redis writes AOF file, some process will monitor this file and sync the updated datas to MySQL
  2. Hack Redis to write AOF in several files, just like MySQL binlog
  3. The data interface will only read and write through Redis
  1. Redis 写入 AOF 文件,某些进程会监视此文件并将更新的数据同步到 MySQL
  2. Hack Redis 将AOF 写在多个文件中,就像MySQL binlog
  3. 数据接口只会通过Redis读写

Is this solution OK?
And what's the best strategy to do this job?

这个解决方案好吗?
完成这项工作的最佳策略是什么?

回答by Javier Ramirez

You don't need to hack anything ;)

你不需要破解任何东西;)

I am not entirely sure why you need the data on mysql. If I knew, maybe there would be a more suitable answer. In any case, as a generic answer you can use redis keyspace notifications

我不完全确定您为什么需要 mysql 上的数据。如果我知道,也许会有更合适的答案。在任何情况下,作为通用答案,您可以使用redis 键空间通知

You could subscribe to the commands HSET, HMSET, HDEL and DEL on your keys, so you would get a notification everytime a key is deleted or a hash value is set or removed.

您可以在您的密钥上订阅命令 HSET、HMSET、HDEL 和 DEL,因此每次删除密钥或设置或删除哈希值时,您都会收到通知。

Note if you miss any notification you would have an inconsistency. So once in a while you could just use the SCAN command to go through all your keys and check on mysql if they need to be updated.

请注意,如果您错过任何通知,则会出现不一致的情况。因此,偶尔您可以使用 SCAN 命令查看所有密钥并检查 mysql 是否需要更新它们。

Another strategy could be maintaining two separate structures. One would be the hash with the values, and the other would be a ZSET of all the values sorted by timestamp of update. The best way to keep both structures up to date would be to write two or three lua scripts (insert/update and delete) that would operate on the hash and the zset atomically.

另一种策略可能是维护两个独立的结构。一个是带有值的散列,另一个是按更新时间戳排序的所有值的 ZSET。保持这两个结构最新的最好方法是编写两个或三个 lua 脚本(插入/更新和删除),它们将原子地操作散列和 zset。

Then you can just periodically query the ZSET for the elements with a timestamp higher than your last sync operation, get all the keys that were updated (it would include deleted keys, unless you want to keep a second ZSET exclusively for those) and then just retrieve all the elements by key and sync to mysql.

然后,您可以定期在 ZSET 中查询时间戳高于上次同步操作的元素,获取所有更新的键(它将包括已删除的键,除非您想专门为这些键保留第二个 ZSET),然后只需通过键检索所有元素并同步到mysql。

Hope it will work for you!

希望它对你有用!

回答by Baoyi Chen

you can implement redis replicationprotocol.
but there is a github projectfor your demands.

您可以实现 redis复制协议。
但是有一个github 项目可以满足您的需求。

the stable version is 2.5.0

稳定版本是 2.5.0

<dependency>
    <groupId>com.moilioncircle</groupId>
    <artifactId>redis-replicator</artifactId>
    <version>2.5.0</version>
</dependency>

回答by songxin

When you update values in Redis,you can put the values in other 'Queue', such as List in Redis.Then consuming the values in Queue and update Mysql.

当你更新Redis中的值时,你可以将这些值放在其他'Queue'中,例如Redis中的List。然后消费Queue中的值并更新Mysql。

If the Redis data isn't too much,just using a Scheduler to batch flush all data to Mysql.

如果Redis的数据不是太多,就用一个Scheduler把所有的数据批量刷新到Mysql即可。