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里阻塞

原文地址:https://www.cnblogs.com/showing/p/11763850.html

时间: 2024-08-02 18:30:51

Redis备忘(二)的相关文章

LaTeX宏包TikZ-UML使用备忘二

代码的文件头与备忘一中的一样,这里不再列出. 示例三 % 51CTO陆巍的博客 \begin{center} \begin{tikzpicture} \begin{umlpackage}[x = 0, y = 0, draw = purple, fill = umlyellow]{Policy} \umlsimpleclass[draw = purple]{Policy Layer} \umlinterface[right = 1cm of Policy Layer, draw = purple

定位代码【备忘二】

_asm    {        call l        l :        pop eax            mov eval, eax    }    wchar_t buf[MAXBYTE] = { 0 };    _ltow_s(eval, buf, 16);

RxJava & RxAndroid备忘

"你问我要去向何方,我指着大海的方向" 今天在刷G+的时候看到Dave Smith推荐了一个视频 <Learning RxJava (for Android) by example> 点进去看了一下,原来是位熟悉的"阿三哥",视频封面如下:(没有歧视的意思,不要喷我啊~,为什么感到熟悉?接着往下看) 几乎同时也看到了JetBrains在G+也推荐了篇在Medium上的博文 <RxAndroid And Kotlin (Part 1)> ,然后

oracle下 启动subversion命令 及 oracle相关服务启动备忘

linux shell下  svnserve - d -r + 目录   例如:svnserve -d -r /svn 启动 svn服务. 访问svn://192.168.0.120/kjcg 测试. 启动oracle: 一.如何启动数据库实例 1.进入到sqlplus启动实例 [[email protected] ~]$ su - oracle --“切换到oracle用户” 2. Password: [[email protected] ~]$ lsnrctl start  --“打开监听”

mysql 常用命令(备忘)

1:使用SHOW语句找出在服务器上当前存在什么数据库:mysql> SHOW DATABASES; 2:2.创建一个数据库MYSQLDATAmysql> CREATE DATABASE MYSQLDATA;3:选择你所创建的数据库 mysql> USE MYSQLDATA; (按回车键出现Database changed 时说明操作成功!) 4:查看现在的数据库中存在什么表mysql> SHOW TABLES;5:创建一个数据库表mysql> CREATE TABLE MYT

备忘:CSS术语词汇表——张鑫旭

一.叨点什么 写文章的时候经常用到一些CSS方面的专业词汇.但是毕竟芳华年少不在,脑袋有点秀逗了,很多名词都记不住,这种感觉比厕所便秘还难受.比如今天居然记不起来公司公认脸蛋最pp的同事的名字,没想到我会记不住美女的名字.我觉得我背后一阵萧瑟的秋风吹起,自己俨然成了漫画里面的程序猿—— 某天闲逛到nimbupani,发现有专门展示CSS术语的文章,哇咔咔,感觉好像咬到一口正宗的高邮咸鸭蛋一样,不过人家的是英文,所以我还要本地化润饰处理,然后,就可以留给自己备忘的哈,的说. 二.CSS词汇我来也

正则表达式入门及备忘

概述 正则表达式,主要是用符号描述了一类特定的文本(模式).而正则表达式引擎则负责在给定的字符串中,查找到这一特定的文本. 本文主要是列出常用的正则表达式符号,加以归类说明.本文仅仅是快速理解了正则表达式相关元字符,作一个备忘,供以后理解更复杂表达式的参考,以后关于正则表达式的相关内容会持续更新本文.示例语言用C# 概述 普通字符 字符集合 速记的字符集合 指定重复次数的字符 匹配位置字符 分支替换字符 匹配特殊字符 组,反向引用,非捕获组 贪婪与非贪婪 回溯与非回溯 正向预搜索.反向预搜索 最

Objective-C教程备忘单

终极版本的Objective-C教程备忘单帮助你进行iOS开发. 想开始创建你的第一个iOS应用程序么?那么看一下这篇很棒的教程吧:Create your first iOS 7 Hello World Application 注:这篇文章我写了三天,可能在一些必要的地方使用了编辑和说明,所以如果有任何疑问和修改建议请在下方评论. 这不是一个初学者指南,也不是关于Objective-C的详细讨论,这是关于常见的和高水平的论题的快速索引. 如果这里有些问题没有涉及到,你也可以查阅以下文章: Obj

解析Path方法备忘

public static String parseDataPath(String dataPath){ StringBuilder parseBld = new StringBuilder(); List<String> parseLst = new ArrayList<String>(); if( StringUtils.isNotEmpty(dataPath) ){ String[] parseArry = dataPath.split("/"); int