Redis备忘(二)
内存回收:
有时候发现10g的Redis删掉1g的key,内存占用没啥变化,因为内存页分配,有的页面可能还存在key,整个页面不能回收。
主从同步:
CAP原理:一致性 可用性 分区容忍性
redis主从是异步同步数据的,所以并不满足一致性要求(redis是最终一致性),主节点修改后,立即返回,即使主从断开,主节点依然正常服务,所以满足可用性。
增量同步:主节点将指令记录在ringbuffer中,从节点执行同步,并向主节点反馈同步到的偏移量,网络环境不好时,buffer中的指令会覆盖,这时候需要快照同步。
快照同步:主库bgsave将内存数据快照到磁盘,再传送到从节点,从加载后通知主节点继续进行增量同步。如果快照时间太长,增量同步的buffer还是会被覆盖,
只能再次快照同步,有可能会快照同步死循环。 所以请务必配置合适的buffer大小。
单个Redis的内存不宜过大,内存太大会导致 rdb 文件过大,主从全量同步延迟太长
Redis无盘复制:
主节点快照同步时,IO太大了,2.8以后可以快照同步时一边遍历内存,一边通过套接字将数据发送到从节点。
集群方案:
1.Sentinel:
主从方案中没法自动切换主从。由此引入Sentinel集群
Sentinel监控主从,如果主挂了自动选择一个最优的从作为主,其他从会和新的主建立主从关系
客户端首先连接sentinel,通过其找到主节点地址
主从切换后客户端会重连新的主,怎么实现:处理修改性命令的时候捕获了一个异常 ReadOnlyError,捕获到后将所有旧连接关闭,重连
2.Codis:
Codis无状态,可以部署多个节点。只是简单将key转发给服务端,将结果返回客户端。
原理:将所有key划分成1024个slot,将客户端传过来的key做crc32后对1024取模决定存到哪个slot,slot对应到后面的多个Redis机器之一。
Codis内部维护了Slot和背后机器的映射关系。不同Codis实例之间用etcd或zk同步槽位映射关系
通过Dashboard 可以修改槽位信息,当修改后,Codis会监听到变化并重新同步槽位关系
执行mget命令时,Codis会将key分散到多个机器查询,然后返回归并结果。
集群扩容:如果查询一个正在迁移的key,Codis会强制该key立即迁移,然后去新机器上查询(所以value别太大)
3.Redis Cluster:
客户端向一个错误的节点发出了指令(即key所在槽位不归自己管理),该节点会让客户端重定向到另一个节点,客户端更新自己的槽位映射表
4. Redis Stream:
和Kafka相比,内部没有partition, 如果想要分区,需要创建多个stream,手动分区
5.监控:info, monitor , 可以通过监控异步同步数据失败次数,据此修改buffer大小
6.分布式锁:
主节点上申请了锁,但是突然主从切换了,锁还没来得及同步, 可以使用Redlock
需要提供多个 Redis 实例,这些实例之前相互独立没有主从关系,加锁时,它会向过半节点发送setnx,过半set成功则加锁成功;
还需要考虑出错重试、时钟漂移等很多细节问题,会造成性能下降。
7.过期策略:
同一时间太多的 key 过期,以至于忙不过来?线上指令出现卡顿?
除了定时遍历(集中处理)之外,它还会使用惰性策略(零散处理)来删除过期的key
1s 10次过期扫描,不会扫描整个过期字典,而是贪心策略:
1.从过期字典中随机 20 个 key,删除过期的
2.过期的 key 比率超过 1/4,重复步骤1
如果大批的key同时过期还是可能线上请求造成卡顿,所以最好给过期时间设置一个随机范围。
8. LRU:
Redis支持maxmemory配置, 超过最大内存后可以有以下几种 maxmemory-policy:
1. noeviction不可写库
2. volatile-lru:尝试淘汰设置了过期时间的key,优先淘汰最少使用的
3. volatile-ttl:跟上面一样,不过剩余ttl小的先淘汰
4. allkeys-lru:淘汰的是全体key,即没过期也会淘汰
5. allkeys-random
6. volatile-random
Redis为实现近似 LRU 算法,它给每个key增加了最后一次被访问的时间戳。执行写操作时,发现内存超过maxmemory,执行一次LRU淘汰算法:
随机采样出5个key,淘汰掉最旧的,如果还是超过maxmemory就继续随机采样淘汰。
9. 删除优化:
del删除的key包含元素过多,也会造成单线程卡顿,4.0引入了unlink 指令,对删除操作懒处理,丢给后台线程异步回收内存
10. 数据安全:rename-command flushall ""
11. 渐进式Rehash: dict结构内部包含两个hashtable,通常情况下只有一个hashtable是有值的; 大字典的扩容比较耗时间,Redis单线程很难承受
迁移数据操作埋伏在当前字典的后续指令中(新的元素挂接到新的数组下面),还会在定时任务中对字典进行主动搬迁。
12. 不要对Redis进行绑核,毕竟还有RDB,AOF这些异步操作
建议设置swappiness
13. 缓存使用的问题:
缓存穿透:
1. 返回空:缺点,需要更多内存,如果是攻击问题更严重,可以设置过期时间
2. 布隆过滤器
3. 高可用+降级
4. 提前演练
缓存无底洞:FaceBook添加更多memcached节点发现性能更差,因为如mget可能需要访问n多个节点(hash到不同节点)
更多的节点不代表更高的性能。
解决:客户端记住可以在哪个节点(其实hash一下就行),对每个节点的key打包好请求,然后多线程从各个节点mget或pipline
14.优化:
1. tcp-backlog
2. swappiness
京东订单的Redis实践:
1. 先更新数据库,再更新缓存
2. 数据一致性保证:循环5次直到成功,解决网络抖动造成失败的概率
还不成功则启动线程扫描库,与缓存比较,更新缓存/或发送一条消息到mq,去更新
网易的Redis技术分享:
遍历时间事件链表中找到即将触发的时间,根据这个值去select里阻塞
Redis备忘(二)的更多相关文章
- JavaScript 教程学习进度备忘(二)
备忘:之前,只将“JS 教程”学习完毕,这篇记录:“JS HTML DOM ”.“JS 对象”.“JS Window”.“JS 库” 书签:跳过:另外跳过的内容有待跟进 _______________ ...
- Redis备忘(一)
hash: 渐进式rehash:同时查询新旧两个hash,然后在后续定时任务以及hash的子指令中,循序渐进将旧的迁移到新的hash表 Redis应用: 1.分布式锁: 实现1:setnx+expir ...
- 11. 星际争霸之php设计模式--备忘模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- Linux常用命令速查备忘
Linux常用命令速查备忘 PS:备忘而已,详细的命令参数说明自己man 一. 启动,关机,登入,登出相关命令 [login] 登录 [logout] 登出 [exit] 登出 [shutdown ...
- Zookeeper + Hadoop + Hbase部署备忘
网上类似的文章很多,本文只是记录下来备忘.本文分四大步骤: 准备工作.安装zookeeper.安装hadoop.安装hbase,下面分别详细介绍: 一 准备工作 1. 下载 zookeeper.had ...
- HTML5终极备忘大全
二.文字备忘之标签 HTML5中新增的标签 <article> 定义文章 <aside> 定义页面内容旁边的内容 <audio> 定义声音内容 <canvas ...
- [转] HTML5终极备忘大全(图片版+文字版)---张鑫旭
by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=1544 一.前言兼图片 ...
- 基于Prism.Windows的UWP开发备忘
以前做UWP开发都是使用MvvmLight,主要是简单易上手,同时也写了很多MvvmLight的开发系列文章: UWP开发必备以及常用知识点总结 UWP开发之Mvvmlight实践九:基于MVVM的项 ...
- Npm vs Yarn 之备忘大全
有则笑话,如此讲到:"老丈人爱吃核桃,昨天买了二斤陪妻子送去,老丈人年轻时练过武,用手一拍核桃就碎了,笑着对我说:你还用锤子,你看我用手就成.我嘴一抽,来了句:人和动物最大的区别就是人会使用 ...
随机推荐
- Docker 01 - CentOS 7 中安装 Docker 的详细步骤
目录 1 初识 Docker 1.1 Docker 原理简介 1.2 Docker 核心概念 2 安装 Docker 2.1 查看系统内核版本 2.2 更新 yum 包 2.3 安装软件包 2.4 向 ...
- Webpack配置区分开发环境和生产环境
在项目开发的时候,我们通常会将程序分为开发环境和生产环境(或者叫线上环境),开发环境通常指的是我们正在开发的这个阶段所需要的一些环境配置,也就是方便我们开发人员调试开发的一种环境:生产环境通常指的是我 ...
- Emacs 笔记二
Emacs 笔记二 Table of Contents 1. 前言 2. emacs基本操作(常用快捷键) 3. emacs模式讲解 4. emacs缓冲区 5. org mode 5.1. 列表 5 ...
- mysql uuid使用
java中可以使用UUID类来生成uuid,使用mysql也可以使用UUID函数来获取uuid,如 select UUID(); 也可以对查询的结果做一些处理,比如说将"-"替换成 ...
- layui select获取自定义属性值
layui-select写法: <option value='> 我想在点击的时候获取自定义属性data-method的值,其中selectId是该select的id form.on('s ...
- Android开发——Toolbar常用设置
本篇笔记用来记录常用的Toolbar设置,如Toolbar颜色设置,显示返回按钮,显示右边三个点按钮 之前Android 使用的ActionBar,Android5.0开始,谷歌官方推荐使用Toolb ...
- MongoDB入门系列之科普篇
目录 背景 对比 MongoDB的数据存储格式 背景 最近公司扩展了很多国外客户,那么一个很严重的问题就是翻译,对于国外客户来说,肯定看不懂中文,那就要项目中提供切换各自国家语言的功能. 由于每个 ...
- 品Spring:关于@Scheduled定时任务的思考与探索,结果尴尬了
非Spring风格的代码与Spring的结合 现在的开发都是基于Spring的,所有的依赖都有Spring管理,这没有问题. 但是要突然写一些非Spring风格的代码时,可能会很不习惯,如果还要和Sp ...
- Web应用程序并发问题处理的一点小经验
在web应用中,一个账户,会有N多个涉及到数字的字段.比如一个账户的金额,积分等.这些字段就涉及到增减的情况.如果是在测试环境下,靠程序员或者测试手动点击.一般是发现不了问题. 一旦上到正式环境下.有 ...
- ASP.NET Web API 2系列(一):初识Web API及手动搭建基本框架
1.导言 随着Web技术的发展,现在各种框架,前端的,后端的,数不胜数.全栈工程师的压力越来越大. PC端,pad端,移动端App(安卓/IOS)的发展,使得前后端一体的开发模式十分笨重.因此,前后端 ...