• Redis 要知道的一点东西(二)


    实践篇

    一些基础可以看上一篇 Redis 一点基础

    数据的适量存储

    1、String 类型的短板?

    String 消耗内存大

    2、为什么 String 类型内存开销大?

    String 类型还需要额外的内存空间记录数据长度空间使用等信息,这些信息也叫作元数据。当实际保存的数据较小时,元数据的空间开销就显得比较大了。

    3、SDS(简单动态字符串)的结构

    image-20210203085923544

    • buf:字节数组,保存实际数据,会在最后面加一个 ,多占用一个字节
    • len:占用四个字节,表示buf的已用长度
    • alloc:占用四个字节,表示buf的实际长度,一般大于 len

    4、什么是Redis Object?

    因为 Redis 的数据类型有很多,而且,不同数据类型都有些相同的元数据要记录(比如最后一次访问的时间、被引用的次数等),所以,Redis 会用一个 RedisObject 结构体来统一记录这些元数据,同时指向实际数据。

    5、Redis Object 的结构是什么样的?

    8 byte 的元数据以及 8 byte的指针(ptr),指针指向具体数据类型的实际数据所在地址,redis object 对 sds 做了单独的优化,如果存入的是:

    • long 整型数组的时候,ptr 为具体的值
    • 如果是字符串类型,且小于 44 byte,元数据、指针和sds是一块连续的内存,并用指针指向sds,raw 编码模式
    • 其他则为指针查找模式

    img

    6、dictEntry 啥样子?

    dictEntry 结构中有三个 8 字节的指针,分别指向 key、value 以及下一个 dictEntry,三个指针共 24 字节:

    img

    7、Redis 内存申请方式

    使用内存分配库 jemallloc,jemalloc 在分配内存时,会根据我们申请的字节数 N,找一个比 N 大,但是最接近 N 的 2 的幂次数作为分配的空间,这样可以减少频繁分配的次数。

    8、保存小数据的时候可以用什么数据结构保存,在Redis中?

    压缩列表

    9、压缩列表保存数据的结构是什么样的?

    压缩列表由一些元数据与真正存储数据的 entry 构成,entry包含以下结构:

    • prev_len:如果上一个 entry 长度小于 254(255被zlend当成默认值使用了,表示压缩列表的结束) 字节,则此值为 1字节,大于254 则采用 5 字节
    • len:表示自身的长度,4字节
    • encoding:表示编码方式 1字节
    • content:保存实际数据

    10、Hash 结构压缩列表与 hash 结构的转换

    • hash-max-ziplist-entries:表示用压缩列表保存时哈希集合中的最大元素个数。
    • hash-max-ziplist-value:表示用压缩列表保存时哈希集合中单个元素的最大长度。

    超过这俩阈值其中的一个就会由压缩列表转化为 hash 存储了

    11、常见的集合统计模式有哪些?

    • 聚合统计
    • 排序统计
    • 二值统计 bitmap
    • 基数统计 hyperloglog pfadd pfcount 有误算率 0.81%

    12、GEO 是怎么实现的?

    GEO 类型的底层数据结构就是用 Sorted Set 来实现的,采用的是 GeoHash 编码,基本原理就是 二分区间,区间编码

    当我们要对一组经纬度进行 GeoHash 编码时,我们要先对经度和纬度分别编码,然后再把经纬度各自的编码组合成一个最终编码。

    13、GeoHash 编码是怎么计算的?

    • 先从单独对经度与维度编码来看
      • 对于一个地理位置信息来说,它的经度范围是[-180,180]。GeoHash 编码会把一个经度值编码成一个 N 位的二进制值,我们来对经度范围[-180,180]做 N 次的二分区操作,其中 N 可以自定义。
      • 在进行第一次二分区时,经度范围[-180,180]会被分成两个子区间:[-180,0) 和[0,180](可称之为左、右分区)。此时,我们可以查看一下要编码的经度值落在了左分区还是右分区。如果是落在左分区,我们就用 0 表示;如果落在右分区,就用 1 表示。这样一来,每做完一次二分区,我们就可以得到 1 位编码值。
      • 重复之前的操作,每次都能获得一位编码,等做完 N 次之后就可以用一个 N bit 的数来表示了
      • 对维度也是一样,只不过维度的范围是[-90,90]
    • 等经纬度都编码完之后,再组合到一起,组合的规则是,偶位数上依次是经度的编码值,奇位数上是维度的编码值,由此得到 sort set 的权重

    为了避免查询不准确问题,可以同时查询给定经纬度所在的方格周围的 4 个或 8 个方格

    14、分布式组件消息队列的需求?

    • 消息保序
    • 重复消费处理
    • 消息可靠性保证

    影响 Redis 性能的潜在方面

    15、与 Redis 交互发生的操作

    • 客户端:网络 IO,键值对增删改查操作,数据库操作;
    • 磁盘:生成 RDB 快照,记录 AOF 日志,AOF 日志重写;
    • 主从节点:主库生成、传输 RDB 文件,从库接收 RDB 文件、清空数据库、加载 RDB 文件;
    • 切片集群实例:向其他实例传输哈希槽信息,数据迁移。

    16、Redis 的阻塞点有哪些?

    • 客户端交互阻塞点
      • 客户端的复杂操作,集合全量查询和聚合操作。
      • bigkey 的删除操作
      • **清空数据库 ** FLUSHDBFLUSHALL
    • 和磁盘交互时的阻塞点
      • AOF 日志同步写
    • 主从节点交互时的阻塞点
      • 从节点加载RDB 文件

    17、redis的删除操作?

    删除操作的本质是要释放键值对占用的内存空间。在应用程序释放内存时,操作系统需要把释放掉的内存块插入一个空闲内存块的链表,以便后续进行管理和再分配。这个过程本身需要一定时间,而且会阻塞当前释放内存的应用程序,所以,如果一下子释放了大量内存,空闲内存块链表操作时间就会增加,相应地就会造成 Redis 主线程的阻塞。

    18、redis 解决部分阻塞点的方式?

    异步的子线程机制,利用操作系统 pthread_create 函数创建 3 个子线程,分别负责 aof 的写操作、键值对删除以及文件关闭的异步执行。

    主线程通过一个链表形式的任务队列和子线程进行交互。

    • aof 被封装成一个任务放入队列,异步执行
    • 异步删除,惰性删除,即使开启了lazy-free,如果直接使用DEL命令还是会同步删除key,只有使用UNLINK命令才会可能异步删除key。
    • 清空数据库用 flushdb async

    19 、lazy_free 是个什么东西?

    lazy-free是4.0新增的功能,但是默认是关闭的,需要手动开启。

    • lazyfree-lazy-expire:key在过期删除时尝试异步释放内存
    • lazyfree-lazy-eviction:内存达到maxmemory并设置了淘汰策略时尝试异步释放内存
    • lazyfree-lazy-server-del:执行RENAME/MOVE等命令或需要覆盖一个key时,删除旧key尝试异步释放内存
    • replica-lazy-flush:主从全量同步,从库清空数据库时异步释放内存

    lazy_free 也不是一直生效的,除了 replica-lazy-flush 以外都只是可能释放;

    开启lazy-free后,Redis在释放一个key的内存时,首先会评估代价,如果释放内存的代价很小,那么就直接在主线程中操作了,没必要放到异步线程中执行(不同线程传递数据也会有性能消耗)。

    20、什么情况 lazy_free 才会真正异步释放内存?

    • 当Hash/Set底层采用哈希表存储(非ziplist/int编码存储)时,并且元素数量超过64个
    • 当ZSet底层采用跳表存储(非ziplist编码存储)时,并且元素数量超过64个
    • 当List链表节点数量超过64个(注意,不是元素数量,而是链表节点的数量,List的实现是在每个节点包含了若干个元素的数据,这些元素采用ziplist存储)

    只有以上这些情况,在删除key释放内存时,才会真正放到异步线程中执行,其他情况一律还是在主线程操作。

    也就是说String(不管内存占用多大)、List(少量元素)、Set(int编码存储)、Hash/ZSet(ziplist编码存储)这些情况下的key在释放内存时,依旧在主线程中操作。

    21、主流的 CPU 架构

    主流 CPU 有物理核,逻辑核,一个 cpu 组成一个 socket,多个cpu通过总线通信,这种架构叫 NUMA 架构(非统一内存访问架构);

    在多 CPU 架构上,应用程序可以在不同的处理器上运行

    d9689a38cbe67c3008d8ba99663c2f09

    在主流的服务器上,一个 CPU 处理器会有 10 到 20 多个物理核。同时,为了提升服务器的处理能力,服务器上通常还会有多个 CPU 处理器(也称为多 CPU Socket),每个处理器有自己的物理核(包括 L1、L2 缓存),L3 缓存,以及连接的内存,同时,不同处理器间通过总线连接。

    5ceb2ab6f61c064284c8f8811431bc3d

    22、什么是尾延迟?

    们把所有请求的处理延迟从小到大排个序,99% 的请求延迟小于的值就是 99% 尾延迟。

    23、context switch

    context switch 是指线程的上下文切换,这里的上下文就是线程的运行时信息。

    24、redis 绑核

    # -c 表示要绑定的核号
    taskset -c 0 ./redis-server
    

    25、绑核的好处?

    • 降低尾延迟
    • 降低平均延迟
    • 提升吞吐率

    26、绑核的风险

    当把 Redis 实例绑定到一个逻辑核的时候,会导致后台线程、进程与 Redis 主进程争抢CPU,主线程就会被阻塞,导致 Redis 延迟增加

    27、怎么解决绑核的问题?

    • Redis 实例对应绑一个物理核
    • 优化 Redis 源码。
    # 绑定0、12 逻辑核,其实是一个物理核
    taskset -c 0,12 ./redis-server
    

    28、怎么检测 Redis 的响应延迟?

    ./redis-cli --intrinsic-latency 120
    

    29、过期 key 操作

    默认情况下,Redis 每 100 毫秒会删除一些过期 key

    • 采样 ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP (默认20)个数的 key,并将其中过期的 key 全部删除;
    • 如果超过 25% 的 key 过期了,则重复删除(阻塞)的过程,直到过期 key 的比例降至 25% 以下。

    为了防止同一时间大量的key过期,给同一批次的数据加上随机过期时间是个不错的选择

    30、替代 keys 的 sacn 命令有什么好处跟问题?

    • 不会漏key:Redis在SCAN遍历全局哈希表时,采用高位进位法的方式遍历哈希桶,当哈希表扩容后,通过这种算法遍历,旧哈希表中的数据映射到新哈希表,依旧会保留原来的先后顺序,这样就可以保证遍历时不会遗漏也不会重复。
    • 可能会得到重复的key:在 hash 桶缩容的时候,会将扫描过的key映射到hash表还没遍历的地方,所以会重复

    scan 是针对所有key的,redis 针对 hash/set/sorted set 也提供了对应的 scan 命令,用于遍历一个key 所有的 value,但是 hscan、sscan、zscan 如果数据比较少的话,底层采用 intsetziplist ,命令会无视 count 参数,将所有的数据都返回出来

    31、什么是 hash tag?

    在键值对的key中使用花括号{},例如{user:}1, {user:}2这样。Redis cluster会针对花括号中的部分进行哈希,这样可以把具有相同前缀的key分配到同一个哈希槽里面。

    可能会导致数据分布不均衡

    32、AOF 数据的流动方向?

    aof 依赖 write 与 fsync 两个系统调用

    • write 只需要把日志写到内核缓冲区就可以返回了
    • fsync 需要把日志记录写到磁盘才能返回,时间较长

    33、不同 AOF 策略对应系统调用

    • no 对应 write,由操作系统来保证刷盘
    • everysec 对应 redis 子线程来调用 fsync ,不阻塞主线程
    • always 对应着 fsync,由主线程调用

    34、Redis 使用 fsync 的阻塞点?

    • fsync需要等到数据写入磁盘才能返回,aof 重写对磁盘 io 压力过大时,就会导致 fsync 阻塞,虽然 fsync 是子线程去做,但是主线程要监控执行的进度。
    • 当主线程使用 子线程 执行了一次 fsync,需要再次把数据写回磁盘的时候,发现上次的fsync还没进行完,则阻塞主线程

    35、怎么让 aof 重写与 fsync 分离?

    如果业务应用对延迟非常敏感,但同时允许一定量的数据丢失,那么可以关闭在 aof 时调用 fsync

    no-appendfsync-on-rewrite yes
    

    这个配置项设置为 yes 时,表示在 AOF 重写时,不进行 fsync 操作。如果设置为 no 的话,redis 实例仍然会调用后台线程进行 fsync,会给实例带来阻塞。

    36、什么是 swap?

    内存 swap 是操作系统里将内存数据在内存和磁盘间来回换入和换出的机制,涉及到磁盘的读写,所以,一旦触发 swap,无论是被换入数据的进程,还是被换出数据的进程,其性能都会受到慢速磁盘读写的影响。

    37、什么时候会触发 swap?

    物理机器内存不足

    • Redis 实例自身使用了大量的内存,导致物理机器的可用内存不足;
    • 和 Redis 实例在同一台机器上运行的其他进程,在进行大量的文件读写操作。文件读写本身会占用系统内存,这会导致分配给 Redis 实例的内存量变少,进而触发 Redis 发生 swap。

    可以增加机器内存或者使用redis cluster

    38、系统大页会给 Redis 带来什么问题?

    因为 redis 大量采用 COW(写时复制)的操作,如果使用系统大页,会将原本只拷贝 4KB 的数据变成拷贝 2MB,影响 Redis 正常的存取操作。

    # always 为启动,never 为关闭
    cat /sys/kernel/mm/transparent_hugepage/enabled
    # 部署时关闭系统大页
    echo never /sys/kernel/mm/transparent_hugepage/enabled
    

    39、如何分析、排查、解决Redis变慢问题?

    1、使用复杂度过高的命令

    (例如SORT/SUION/ZUNIONSTORE/KEYS),或一次查询全量数据(例如LRANGE key 0 N,但N很大)

    分析:

    • 查看slowlog是否存在这些命令
    • Redis进程CPU使用率是否飙升(聚合运算命令导致)

    解决:

    • 不使用复杂度过高的命令,或用其他方式代替实现(放在客户端做)
    • 数据尽量分批查询(LRANGE key 0 N,建议N<=100,查询全量数据建议使用HSCAN/SSCAN/ZSCAN)

    2、操作bigkey

    分析:

    • slowlog出现很多SET/DELETE变慢命令(bigkey分配内存和释放内存变慢)
    • 使用redis-cli -h $host -p $port --bigkeys扫描出很多bigkey

    解决:

    • 优化业务,避免存储bigkey
    • Redis 4.0+可开启lazy-free机制

    3、大量key集中过期

    分析:

    • 业务使用EXPIREAT/PEXPIREAT命令
    • Redis info中的expired_keys指标短期突增

    解决:

    • 优化业务,过期增加随机时间,把时间打散,减轻删除过期key的压力
    • 运维层面,监控expired_keys指标,有短期突增及时报警排查

    4、Redis内存达到maxmemory

    分析:

    • 实例内存达到maxmemory,且写入量大,淘汰key压力变大
    • Redis info中的evicted_keys指标短期突增

    解决:

    • 业务层面,根据情况调整淘汰策略(随机比LRU快)
    • 运维层面,监控evicted_keys指标,有短期突增及时报警
    • 集群扩容,多个实例减轻淘汰key的压力

    5、大量短连接请求

    分析:

    • Redis处理大量短连接请求,TCP三次握手和四次挥手也会增加耗时

    解决:

    • 使用长连接操作Redis

    6、生成RDB和AOF重写fork耗时严重

    分析:

    • Redis变慢只发生在生成RDB和AOF重写期间
    • 实例占用内存越大,fork拷贝内存页表越久 c) Redis info中latest_fork_usec耗时变长

    解决:

    • 实例尽量小
    • Redis尽量部署在物理机上
    • 优化备份策略(例如低峰期备份)
    • 合理配置repl-backlog和slave client-output-buffer-limit,避免主从全量同步
    • 视情况考虑关闭AOF
    • 监控latest_fork_usec耗时是否变长

    7、AOF使用awalys机制

    分析:

    • 磁盘IO负载变高

    解决:

    • 使用everysec机制
    • 丢失数据不敏感的业务不开启AOF

    8、使用Swap

    分析:

    • 所有请求全部开始变慢
    • slowlog大量慢日志
    • 查看Redis进程是否使用到了Swap

    解决:

    • 增加机器内存
    • 集群扩容
    • Swap使用时监控报警

    9、进程绑定CPU不合理

    分析:

    • Redis进程只绑定一个CPU逻辑核
    • NUMA架构下,网络中断处理程序和Redis进程没有绑定在同一个Socket下

    解决:

    • Redis进程绑定多个CPU逻辑核
    • 网络中断处理程序和Redis进程绑定在同一个Socket下

    10、开启透明大页机制

    分析:

    • 生成RDB和AOF重写期间,主线程处理写请求耗时变长(拷贝内存副本耗时变长)

    解决:

    • 关闭透明大页机制

    11、网卡负载过高

    分析:

    • TCP/IP层延迟变大,丢包重传变多
    • 是否存在流量过大的实例占满带宽

    解决:

    • 机器网络资源监控,负载过高及时报警
    • 提前规划部署策略,访问量大的实例隔离部署

    内存整理

    40、如何判断是否有内存碎片?

    info memory 命令里面的 mem_fragmentation_ratio指标就是 Redis 当前的内存碎片率

    used_memory_rss 表示操作系统分配给 Redis 物理内存空间,里面包含了碎片,used_memory 表示 Redis 申请了多少空间 mem_fragmentation_ratio = used_memory_rss/ used_memory

    41、怎么判断是否超过了阈值?

    • mem_fragmentation_ratio 大于 1 但小于 1.5。这种情况是合理的。
    • mem_fragmentation_ratio 大于 1.5 。这表明内存碎片率已经超过了 50%。一般情况下,这个时候,我们就需要采取一些措施来降低内存碎片率了。

    42、如何清理内存碎片?

    • 重启
    • 4.0-RC3 版本以后,有自动清理的功能,压缩内存

    43、Redis 怎么开启自动清理?

    # 开启自动清理配置
    config set activedefrag yes
    

    44、redis 什么时候自动清理?

    • active-defrag-ignore-bytes 100mb:表示内存碎片的字节数达到 100MB 时,开始清理;
    • active-defrag-threshold-lower 10:表示内存碎片空间占操作系统分配给 Redis 的总空间比例达到 10% 时,开始清理。

    为了减轻自动清理对主线程的影响,redis 设置了两个参数用来保证:

    • active-defrag-cycle-min 25:表示自动清理过程所用 CPU 时间的比例不低于 25%,保证清理能正常开展;
    • active-defrag-cycle-max 75:表示自动清理过程所用 CPU 时间的比例不高于 75%,一旦超过,就停止清理,从而避免在清理时,大量的内存拷贝阻塞 Redis,导致响应延迟升高。

    45、客户端为什么需要用到缓冲区?

    • 一方面,可以在客户端控制发送速率,避免把过多的请求一下子全部发到 Redis 实例,导致实例因压力过大而性能下降。不过,客户端缓冲区不会太大,所以,对 Redis 实例的内存使用没有什么影响。
    • 另一方面,在应用 Redis 主从集群时,主从节点进行故障切换是需要一定时间的,此时,主节点无法服务外来请求。如果客户端有缓冲区暂存请求,那么,客户端仍然可以正常接收业务应用的请求,这就可以避免直接给应用返回无法服务的错误。

    库上的从库输出缓冲区(slave client-output-buffer)是不计算在Redis使用的总内存中的,也就是说主从同步延迟,数据积压在主库上的从库输出缓冲区中,这个缓冲区内存占用变大,不会超过maxmemory导致淘汰数据。只有普通客户端和订阅客户端的输出缓冲区内存增长,超过maxmemory时,才会淘汰数据。

    46、怎么使用 redis 的慢日志?

    设置阈值:

    • slowlog-log-slower-than:慢查询日志对执行时间大于多少微秒的命令进行记录。
    • slowlog-max-len:记录多少条数,默认128,建议改成1k,底层是队列实现,超过阈值则被删除
    slowlog get 1
    

    47、如何排查 Redis 的 bigkey?

    # 对整个数据库中的键值对大小情况进行统计分析
    ./redis-cli --bigkeys
    

    48、Redis 做缓存的时候,缓存的类型有哪些?

    • 只读缓存 修改数据则删掉缓存中的数据
    • 读写缓存

    49、怎么解决 Redis 做读写缓存时的缺陷?

    • 可靠性保证:同步直写。写请求发给缓存的同时,也会发给后端数据库进行处理,等到缓存和数据库都写完数据,才给客户端返回。速度慢。
    • 快速响应:异步写回。所有写请求都先在缓存中处理,等到这些增改的数据要被从缓存中淘汰出来时,缓存将它们写回后端数据库。如果掉电则丢失数据。

    50、怎么设置 Redis 缓存的大小?

    conifg set maxmemory 4gb
    

    一般建议设置成总数据量的15% - 30%

    51、缓存淘汰策略?

    noeviction、volatile-ttl、volatile-random、volatile-lru、volatile-lfu、allkeys-lru、allkeys-lfu、allkeys-random

    52、Redis 中的 Lru 算法有啥区别?

    LRU 算法被做了简化,Redis会将最近访问时的时间戳记录在 Redis Object 中 lru 字段中,redis 执行定期淘汰策略,第一次选出 N 个数据,把其当成一个候选集合,然后比较这 N 个数据的 lru 的值,把 lru 最小的值淘汰出去。

    # 设置 N 的大小,默认是5,建议改为10
    CONFIG SET maxmemory-samples 10
    # 容量大小
    evictionPoolEntry 的容容量是 EVPOOL_SIZE = 16;
    
    • 当再次进行定期淘汰的时候,再挑选一批新的数据,但是能进入集合的只有 lru 小于现集合最小的 lru 的值才可以,当达到了 maxmemory-samples 的值后,redis 把集合中lru最小的值踢掉。
    • 每次淘汰的数量是根据内存量超过 maxmemory 的情况来决定的,所以每次加进集合的数据量也不是只有一个。
    • 准备要淘汰的数据与淘汰数据是两个操作
    • 当淘汰集合中没有位置的时候,新进来的数据小于最小 lru,集合头部存放的是最大的 lru,所以会把头部的数据依次移出集合,将更古老的数据存放到集合链表的尾部。

    53、什么是缓存污染?

    仅仅被访问少数次的数据被大量放在缓存里面

    54、LFU 缓存策略的优化

    LFU 缓存策略是在 LRU 策略基础上,为每个数据增加了一个计数器,来统计这个数据的访问次数。当使用 lfu 策略的时候,首先根据计数器筛选,把访问次数最低的淘汰出去,如果两个数据访问次数相同,则比较时间戳,淘汰最小的。

    55、LFU 是怎么计算出数据的?

    Redis 在实现 LFU 策略的时候,只是把原来 24bit 大小的 lru 字段,又进一步拆分成了两部分。

    • 前16位为访问的时间戳
    • 后8位为数据访问的次数

    56、8 位最高才255,LFU 是怎么做的?

    使用 非线性递增的计数器方法

    double r = (double)rand()/RAND_MAX;
    // baseval是计数器,初始默认值是 5,LFU_INIT_VAL 常量设置,避免数据刚被写入缓存,就因为访问次数少而被立即淘汰
    double p = 1.0/(baseval * server.lfu_log_factor + 1);
    if (r < p) counter++;   
    

    57、LFU 的衰减策略是什么?

    Luf 的次数不能只加不减,所以有衰减策略,如果 lfu_decay_time 为 1 的话,N 分钟就要被减 N,如果设置的很大则会衰减的缓慢很多。

    58、Redis 针对过期数据的删除策略有哪些?

    • 惰性删除
    • 定期删除
    • 定时删除

    60、Redis 主从模式下过期数据有什么问题?

    • 惰性删除时,访问从库并不会触发主库的删除策略,3.2 以前读取过期数据,从库会返回过期数据,3.2 以后返回空值
    • EXPIRE 和 PEXPIRE:它们给数据设置的是从命令执行时开始计算的存活时间,可能会导致数据延迟

    可以使用 EXPRIEAT / PEXPIREAT 时间戳 来控制统一的过期事件

    61、主从的一个小问题 protected-mode

    如果设置 protected-mode yes 的话,哨兵只能被当前服务器的实例访问,会引发一系列的问题,建议设置为no,并且 bind 参数设置为主从节点的 ip

    62、为什么脑裂导致了redis的部分数据丢失?

    在脑裂的时候有服务还在连接原来的主库,哨兵集群判断主库下线,从库被选举为主库,而等 redis 原主库回复的时候,服务写在原服务里面的数据因为redis被变成 现主库的从库,要发生一次全量复制,导致期间产生的数据丢失。

    63、如何应对脑裂问题?

    • min-slaves-to-write:设置了主库能进行数据同步最少的从库数量 N
    • min-slaves-max-lag:设置从库给主库发送ack消息的最大延迟 T

    如果主库连接从库数量少于N,或主从数据复制时ack消息延迟超过T,则主库不会接收客户端发来的消息了

    64、若从库能删数据,有什么风险??

    • 原本主库快要过期的 key 用 expire 续命了,但是因为有延迟,从库正好也删掉了,就会导致数据不一致
    • 主从库的时钟不同步,导致主从库删除时间不一致

    65、如何理解把 Redis 称为旁路缓存?

    业务应用在使用 Redis 缓存时,需要在业务代码中显式地增加缓存的操作逻辑。

    66、秒杀支持

    • 前端静态页面的设计,秒杀页面能静态化的都要静态化,充分利用 CDN 与浏览器缓存
    • 请求拦截和流控,拦截恶意请求,为防止 Redis 流量过大,在接入层进行限流,如控制进入秒杀的数量
    • 库存信息过期时间处理,不给秒杀商品设置过期事件,防止击穿
    • 数据库订单异常处理,如果数据库没能处理成功,增加重试功能,保证订单能被最终处理
    • 秒杀数据单独保存,建议秒杀商品的信息用单独的实例去保存

    67、数据倾斜是怎么产生的?

    • bigkey
    • Slot 分配不均衡,CLUSTER SLOTS 可查看 slot 的信息
    • Hash Tag

    68、数据倾斜的解决方案

    数据倾斜基本原因还是热点数据的问题,同长缓存还是读多一些,可以采用热点数据多副本的方式,把热点数据复制多份,在每个数据副本前增加一个前缀,这样热点数据的压力被分散到不同的实例上去了

    此方法只针对 读热点数据

    69、Redis cluster 集群通讯方式 gossip 是什么原理?

    • 集群中的会按照一定的频率选出一些实例,把ping命令发送给选出的实例,交换彼此的信息,ping中封装了发送消息的实例自身的状态信息、部分其他实例的状态信息,以及 slot 表
    • 一个实例接收到 ping 后,会发送 pong 给消息实例,包含的信息与 ping 一样

    Gossip 协议可以保证在一段时间后,集群中的每一个实例都能获得其它所有实例的状态信息。

    ZGC说:有什么能比不给牛吃草,还挤牛奶更快乐的事情呢?
  • 相关阅读:
    The Problem Came Up when we upgrade from KingDee K3 to SAP R3(FI module)
    小代码 OpenFileDialog() Windows下Upload & rewrite 文件
    [Note]CodeSmith 4.0 Lesson One
    正则表达式 运算 常见
    SAP function overview & instruction
    CodeSmith NetTier 保存主从表实例,当然,至于3级关联的问题还是类似做法,依靠Relationship做级联更新
    CodeSmith NetTier模板生成的代码框架用法 (转)
    [Notes] Demo The practice about how to using SAP XI components to build up the mapping bridge cross the application layer
    6260/7610/6670/3230 蓝牙 共享PC 宽带 无须代理
    [ALE in SAP]BAPI Introduction
  • 原文地址:https://www.cnblogs.com/lovestart/p/14399881.html
Copyright © 2020-2023  润新知