mysql缓存策略

文章探讨了如何使用Redis作为MySQL缓存以减轻压力,比较了changebuffer和Redis缓存的差异。还介绍了读写分离、连接池、异步连接等提升性能的方法,以及如何通过触发器和伪装从数据库实现数据同步。同时讨论了缓存方案的局限性和故障处理,以及事务一致性的问题。
摘要由CSDN通过智能技术生成

mysql缓存方案用来干什么

        比如直接和mysql交互会造成mysql很大的压力,现在在mysql前面增加redis充当缓存;也可以把redis替换为memcached;因为mysql做增删改操作的时候必须要落盘,访问redis的效率要远远高于mysql;

        mysql中有change buffer缓存,那么为什么还要增加redis缓存中间件呢?因为change buffer缓存针对的是lru淘汰策略,主要是针对最近访问的数据,但是没法缓存用户访问的热点数据;

还有哪些方案可以提升mysql访问性能

        读写分离,分担读写压力,因为读的操作较多,所以直接往从数据库中读,写的操作较少,所以直接操作主数据库;

        redolog用于事务持久化/确保本地数据一致;

        binlog用于数据备份/主从复制,确保主从数据一致;

        mysql主从复制中,从数据库会主动和主数据库建立连接,建立连接后会产生log dump thread线程,该线程从binlog读数据并发送到从数据库;从数据库读到binlog后会通过io thread写到relay log中;sql thread线程会从relay log读取日志后进行重放replay,即重新执行sql语句,就可以应用到从数据库;可以看到这是一种异步复制;说明同一时刻主从数据库的数据可能不一致,这是读写分离可能就有问题,可能读到的不是最新数据;所以读写分离保证的是最终一致性,而不是实时一致性;如果要求是强一致性的,即要求确保读到的数据一定是最新的数据,我们可以从主数据库中去读;

        连接池

        异步连接

缓存方案是怎么解决的?

        热点数据放到redis中,服务器读数据的时候从redis中读,如果不是热点数据依然从mysql读;mysql和redis是独立的进程;现在将mysql和redis作为整体看作db;这种情况下可能出现几种状态;

        1)mysql有数据,redis中没有;通过同步可以一致;

        2)mysql没有数据,redis中有;

        3)都有数据·,但是数据不一致;

        4)都有数据,且数据一致;

        5)都没有;

        这里只有2,3情况需要制定读写策略来避免;

        读策略,在server层写逻辑,如果是热点数据则从redis中读数据,如果不是热点数据则从mysql中读数据;如果mysql中可以读到数据则同步到redis,如果读不到数据则返回没有;

        写策略,一定要确保是4;

                1)安全优先;先删除缓存,然后写mysql,接着mysql把数据同步到redis;同一个key必须要走同一个mysql连接,同一个redis连接,通过hash实现;确保同一个key没有并发问题;有一条连接在访问某个key,不可能有另一条连接也在访问这个key;安全优先效率较低;

                2)效率优先;先写redis,若是插入和更新,把key设置过期时间,再写mysql,最后mysql同步到redis;过期时间设置为server把数据发送到mysql然后同步到redis这个过程所花的时间;工作当中用到的是效率优先的策略;虽然有安全性的问题,但是只会影响设置的过期时间这段时长;

如何把mysql数据同步到redis?有很多开源方案;

        1)触发器+udf,触发器对表进行增删改操作,会触发行为把mysql数据同步到redis中;udf即user define function,我们可以用c/c++实现udf,在实现中与redis建立连接并把数据进行同步;把热点数据表设置触发器,然后在触发器中调用udf,udf与redis建立连接并把数据同步到redis;触发器中有有种数据,一种是new即新增的数据,一种是old即原来的数据,old存储在undolog中;

        2)伪装从数据库,一种是阿里开源的canal,一种是go-mysql-transfer;

        阿里开源的canal,canal主动与mysql建立连接,往mysql拉取binlog,canal client不断的从canal中拉数据并将数据写到redis;这种方案的有点是解决了可用性的问题,有可替换的节点,分布式考虑的更多;

        go-mysql-transfer伪装成从数据库,并从mysql拉取数据,拉完数据后直接写redis;但是没有解决分布式的问题;

        代码路径

                git clone https://gitee.com/josinli/mysql_redis.git

                git clone https://gitee.com/mirrors/go-mysql-transfer.git

缓存方案的故障问题及解决

缓存方案的弊端是不能处理多语句的事务,因为redis不支持回滚,造成redis和mysql数据不一致;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值