当前位置:首页 > 问答 > 正文

用Redis怎么连远程数据库实现数据实时传输那事儿,聊聊连接和同步的那些细节

这事儿说白了,就是想让你放在不同地方的两个“数据仓库”(一个是Redis,另一个比如是MySQL)能说上话,一个有点风吹草动,另一个马上就知道,并且跟着动,核心就是“连接”和“同步”这两个动作。

先聊聊“连接”这事儿

你想让Redis去连一个远程的数据库,比如一台不在你本机的MySQL,首先得让它们俩能接上头,这不像我们人打招呼握个手就行,机器之间得靠网络和协议。

用Redis怎么连远程数据库实现数据实时传输那事儿,聊聊连接和同步的那些细节

(来源:常见的数据库连接知识)第一步,你得确保网络是通的,你的Redis客户端或者同步程序所在的那台机器,要能通过网络访问到远程数据库那台机器的IP地址和端口号(比如MySQL默认是3306端口),这就好比你知道朋友家的地址和门牌号,并且路是通的,你才能去串门,要是有防火墙拦着,你就得把防火墙的规则改一下,允许这个连接通过。

(来源:数据库连接驱动)第二步,你得有个“翻译官”,也就是数据库驱动,Redis本身不会说MySQL的语言(SQL),所以你需要一个程序(比如用Java写的就用JDBC,用Python写的就用PyMySQL)来充当这个翻译官,这个程序会负责建立到MySQL的网络连接,并且把你要做的事情(比如查询数据、监听变化)翻译成MySQL能听懂的命令。

“连接”的本质就是:在你的同步程序里,使用正确的数据库驱动,配置好远程数据库的地址、端口、用户名、密码,建立起一条可靠的网络链路。

用Redis怎么连远程数据库实现数据实时传输那事儿,聊聊连接和同步的那些细节

再重点说说“同步”的那些细节

连接建好了,怎么实现“实时”同步呢?这是个关键,你不能隔一个小时才去数据库里看一眼有没有新数据,那就不叫实时了。

(来源:数据库的二进制日志机制)这里有个聪明的办法,不是让Redis不停地去问MySQL“你有新数据了吗?”,而是让MySQL在数据发生变化时,主动“喊一嗓子”,对于MySQL来说,这“一嗓子”就是二进制日志,MySQL会把所有对数据有改动的操作(比如增、删、改)都按顺序记录在这个日志文件里,这就好比MySQL有一个忠实的小秘书,把老板做的每一个决策都记在了小本本上。

用Redis怎么连远程数据库实现数据实时传输那事儿,聊聊连接和同步的那些细节

我们的同步程序要做的,就是去“盯住”这个小本本,这个动作叫监听binlog,同步程序会像一个认真的读者一样,持续地从binlog里读取最新的记录,一旦读到一条新记录,在用户表里插入了一条id=123的数据”,它立马就明白了:“哦,MySQL里刚加了个新用户。”

接下来就是同步程序发挥作用的时候了,它拿到这条变更信息后,需要做出反应,让Redis里的数据和MySQL保持一样,这里通常有两种做法:

  1. 直接更新缓存:同步程序解析出binlog里的关键数据(比如那个新用户的id和名字),然后直接在Redis里执行一条命令,比如HSET user:123 name "张三",这样,Redis里立刻就有了这条新数据。
  2. 失效缓存:Redis里的数据可能是经过复杂计算的结果,直接更新比较麻烦,同步程序可以采取一种更简单的策略:它发现MySQL的某张表有数据变了,就直接把Redis里与这张表相关的缓存数据删除(比如DEL user_cache:123),这样,当应用程序下次需要读取这个用户数据时,发现Redis里没有了,就会自己去MySQL查,然后把查到的结果再塞回Redis,这种方法叫“延迟加载”,虽然不是瞬间同步,但能保证下一次读取的数据一定是新的,也基本实现了数据的最终一致性。

你会发现,无论哪种方法,核心都在于那个监听binlog的同步程序,这个程序是连接MySQL和Redis的桥梁,是实现实时性的关键,它需要稳定可靠,7x24小时不停地工作,不能轻易掉线,它还要能处理各种意外情况,比如网络突然中断了怎么办?中断后又恢复了,怎么能从上次断开的地方继续读取binlog,而不是从头开始?这都需要在程序里做精心设计,比如记录已经处理到的binlog位置点。

总结一下

用Redis连远程数据库搞实时同步,不是Redis直接去连,而是需要一个中间的“同步程序”,这个程序干两件大事:一是用数据库驱动连上远程MySQL;二是像侦探一样盯紧MySQL的binlog日志,一旦发现数据变动,它就立刻行动,要么直接给Redis更新数据,要么让Redis的旧缓存失效,从而巧妙地实现两边数据的“准实时”同步,整个过程,网络畅通是基础,监听binlog是精髓,而那个默默工作的同步程序则是无名英雄。