Redis与数据库数据同步解决方案

宋鑫    2016-06-23

本文:Redis与数据库数据同步解决方案,原创于:宋鑫的官方网站,转载请注明出处,谢谢。

目前在中集电商工作,最近在做一个Redis箱格信息同步到数据库Mysql中的功能。

首先我们要考虑的是一个方向性的问题:
是将Redis中的数据同步到数据库中去,还是将数据库中的数据同步到Redis中去?

数据库同步到Redis

我们大多倾向于使用这种方式,也就是将数据库中的变化同步到Redis,这种更加可靠。
Redis在这里只是做缓存。

方案一:

做缓存,就要遵循缓存的语义规定:
读:读缓存redis,没有,读mysql,并将mysql的值写入到redis。
写:写mysql,成功后,更新或者失效掉缓存redis中的值。

对于一致性要求高的,从数据库中读,比如金融,交易等数据。其他的从Redis读。
这种方案的好处是由mysql,常规的关系型数据库来保证持久化,一致性等,不容易出错。

方案二:

这里还可以基于binlog使用mysql_udf_redis,将数据库中的数据同步到Redis。
但是很明显的,这将整体的复杂性提高了,而且本来我们在系统代码中能很轻易完成的功能,现在需要依赖第三方工具,
而且系统的整个边界扩大了,变得更加不稳定也不好管理了。

Redis同步到数据库

也就是说将Redis中的数据变化同步到数据库,那么这里是将Redis做为db,而真的db,数据库只作为备份。
(注意,这里是一种不同看待事物的方式)
这样做的好处是:大大减小了数据库的压力,但是用redis做内存数据库,状态很不稳定,
虽然redis也有持久化机制,但是redis集群宕机后的重启,数据加热都很耗时。
另一方面,随着大量插入或者更新导致redis持久化操作会严重拖累作为内存KV数据库的优势。

方案一:

将redis变更复制一份,丢到队列中,给mysql消费。
很明显这种方案,只能保证最终一致性,而且变更数据复制,队列维护,这些杂七杂八的东西太复杂,抛弃。
具体做法是:写redis时,同时将数据写到redis维护的另外一个队列中,但这样又要增加内存消耗了。

其实还有一种方式是使用redis的pipeline通知机制,但是redis是不保证的一定通知到的(得到被通知方的ack)。

方案二:

定时刷新redis中的最新数据到mysql。
很明显的,无论定时任务的间距有多小,都会留下时间缝隙,如果发生宕机,故障等都会造成数据的不一致性。
虽然可以通过:比较redis和数据库中的数据,同步那些需要同步的变化数据,但是会加大计算量和程序的复杂度。

总结

个人偏向于使用将redis做缓存,这是一种成熟做法。
如果你非要将redis做db,而同步变换到数据库,那么你将失去很多关系型数据库的特性。

相关阅读

使用Maxwell Kafka和Maxwell-Sink进行MySql数据同步


文章有用?分享给你的朋友们,让更多的人受益


更多精彩干货,尽请关注我的个人微信公众号
wechat