redis在使用过程中明明内存充足但是插入数据失败怎么排查?
- 是否是网络问题:客户端使用脚本定时ping Redis服务器,未有丢包情况,排除网络问题。
- 是否是连接池满了:客户端连接池满了,检查客户端连接最大限制maxActive是否足够,Redis服务端连接溢出,无法分配新的连接,检查服务端连接是都达到最大值。
- 是否内存不足:看似内存足够,但是redis在保存内存数据到磁盘时候,为了防止主进程假死,会fork一个子进程来完成这个操作,但是这个fork的子进程需要分配和主进程完全相同的内存,此时相当于内存翻倍了,这个时候内存不足以分配fork子进程所需内存,将会导致fork子进程失败无法保存数据到磁盘。
有哪些因素可能导致Redis出现性能问题?
- Redis内部的阻塞式操作:
集合全量查询和聚合操作。
清空数据库,比如flushall flushdb。
AOF日志同步写。
从库加载RDB文件。 - Redis的系统配置:
AOF日志重写的时候需要大量IO操作,虽然fsync是fork子线程在执行,但是主线程会监控子线程,如果需要再次执行fsync的时候,主线程发现上一次的fsync还没有执行完,那么就会阻塞。
内存大叶机制:linux从2.6.38版本开始支持内存大叶机制,该机制支持2MB的内存叶分配,常规的内存叶分配是按4KB的粒度来执行的,为了保证数据的可靠性保证,需要将数据做持久化保存,Redis客户端写请求可能会修改正在进行持久化的数据, 在这一过程中,Redis就会采用写时复制机制,简单来说就是一旦有数据被修改,Redis并不会直接修改内存的数据,而是将这一部分数据拷贝一部分,然后再进行修改,如果采用了内存大叶,那么即使客户端修改了10KB数据,redis也需要拷贝2MB的的大叶数据,如果采用常规内存叶的话,则只需要拷贝4KB。 - Redis内存碎片:数据删除后,Redis的内存并不会马上被回收,释放的内存会交由Redis的内存分配器管理,这时候操作系统肯定还是记录Redis使用了这部分内存,Redis释放的空间可能不是连续的,这就是Redis的内存碎片。
什么时候会发生Redis的ASK重定向?ASK的流程?
当一个slot数据从源节点迁移到目标节点的时候,会出现部分数据在源节点上部分数据在目标节点上,这个时候如果客户端来请求数据,流程如下:
- 客户端根据本地slots缓存发送命令到源节点,如果存在键对象则直接执行并返回结果给客户端。
- 如果数据不存在源节点,则可能存在于目标节点,这时源节点会回复ASK重定向异常,格式如下:(error)ASK{slot}{targetIP}:{targetPort}。
- 客户端从ASK中获取目标节点的信息,在将命令发送到目标节点,存在则返回数据,不存在就返回不存在的信息。
Redis ASK与MOVED的区别?
ASK和MOVED都是对客户端的重定向控制,但是有着本质的区别,ASK重定向说明集群正在进行slot数据迁移,客户端无法知道什么时候 迁移完成,因此只能是临时性的重定向,客户端不会更新slots缓存,但是MOVED重定向说明键对应的槽已经明确指定到新的节点,因此需 要更新slots缓存。
Redis在使用过程中明明内存充足但是插入数据失败怎么排查?
- 是否是网络问题,客户端使用脚本定时ping redis服务器,未有丢包情况,排除网络问题。
- 是否是连接池满了,客户端连接池满了,检查客户端连接最大限制maxActive是否足够,redis服务端连接溢出,无法分配新的连接,检查服务端连接是都达到最大值。
- 是否内存不足,看似内存足够,但是redis在保存内存数据到磁盘时候,为了防止主进程假死,会fork一个子进程来完成这个操作,但是这个fork的子进程需要分配和主进程完全相同的内存,此时相当于内存翻倍了,这个时候内存不足以分配fork子进程所需内存,将会导致fork子进程失败无法保存数据到磁盘。
Redis-MySQL缓存一致性了解吗?缓存一致性方案有哪些?
缓存一致性,MySQL数据库的数据和Redis的缓存数据保证一致,而在使用缓存的时候就需要特别注意缓存一致性的问题,常用的缓存一致性策略有以下几种:
- 延时双删除策略,在写库前后都进行Redis.del(key)操作,并且设定合理的超时时间,具体是删除缓存,再写数据库,休眠一定时间,再次删除,此方案有短暂的数据不一致性的可能。
- 订阅MySQL master节点的binglog,消费修改删除binglog语句,binglog相当于一个顺序队列,能够保证对数据操作的顺序性,只要数据库事务完成,提交binglog日志后,根据binglog日志顺序更新缓存,可以保证数据的强一致性,此方案的缺点是需要引入其他组件,如阿里的canal,增加了系统的复杂性。
- 使用分布式锁,实现缓存一致性,刷新缓存的时候锁定资源,保证同一时间只能有一个客户端刷新缓存。
持续更新ing
如有不正确的地方请各位指出纠正。