22 | 第11~21讲课后思考题答案及常见问题答疑

115 阅读5分钟

问题:除了 String 类型和 Hash 类型,还有什么类型适合保存第 11 讲中所说的图片吗?

  • 使用zset,当元素较少时仍然是压缩列表
  • 图片前7位Sorted Set 的 key,后3位作为member 值,图片存储id作为score值(会根据score排序,导致插入性能很低)

问题:我在第 12 讲中介绍了 4 种典型的统计模式,分别是聚合统计、排序统计、二值状态统计和基数统计,以及它们各自适合的集合类型。你还遇到过其他的统计场景吗?用的是什么集合类型呢?

使用list统计触达率

\

问题:你在日常的实践过程中,还用过 Redis 的其他数据类型吗?

  • HyperLogLog\

  • Bitmap\

  • GEO\

  • 布隆过滤器\

\

问题:在用 Sorted Set 保存时间序列数据时,如果把时间戳作为 score,把实际的数据作为 member,这样保存数据有没有潜在的风险?

另外,如果你是 Redis 的开发维护者,你会把聚合计算也设计为 Sorted Set 的一个内在功能吗?

  • 相同 member 的值,在 Sorted Set 中只会保留一个,造成数据丢失\

  • 使用单线程聚合,阻塞风险太大

\

问题:如果一个生产者发送给消息队列的消息,需要被多个消费者进行读取和处理?

  • Redis 基于字典和链表数据结构,实现了发布和订阅功能,这个功能可以实现一个消息被多个消费者消费使用,可以满足问题中的场景需求\

\

问题:Redis 的写操作(例如 SET、HSET、SADD 等)是在关键路径上吗?

  • 在关键路径上
  • sync到磁盘不在关键路径上 可以使用异步改造

\

问题:在一台有两个 CPU Socket(每个 Socket 8 个物理核)的服务器上,我们部署了一个有着 8 个实例的 Redis 切片集群(8 个实例都为主节点,没有主备关系),现在有两个方案:

在同一个 CPU Socket 上运行 8 个实例,并和 8 个 CPU 核绑定;

在两个 CPU Socket 上各运行 4 个实例,并和相应 Socket 上的核绑定。如果不考虑网络数据读取的影响,你会选择哪个方案呢?

  • 使用方案2

    • L3使用者多,会导致竞争多,导致缓存命中率
    • 内存不够会涉及跨socket进申请内存

\

问题:在 Redis 中,还有哪些命令可以代替 KEYS 命令,实现对键值对的 key 的模糊查询呢?这些命令的复杂度会导致 Redis 变慢吗?

  • 使用SCAN命令,集合类型的SSCAN、HSCAN 等
  • 避免一次返回所有数据
  • SCAN user 0 match "103*" 100\

\

问题:你遇到过 Redis 变慢的情况吗?如果有的话,你是怎么解决的呢?

  • checklist

    • 使用复杂度过高的命令或一次查询全量数据
    • 操作 bigkey
    • 大量 key 集中过期
    • 内存达到 maxmemory
    • 客户端使用短连接和 Redis 相连
    • 当 Redis 实例的数据量大时,无论是生成 RDB,还是 AOF 重写,都会导致 fork 耗时严重
    • AOF 的写回策略为 always,导致每个操作都要同步刷回磁盘
    • Redis 实例运行机器的内存不足,导致 swap 发生,Redis 需要到 swap 分区读取数据
    • 进程绑定 CPU 不合理
    • Redis 实例运行机器上开启了透明内存大页机制(内存碎片,避免频繁扩容,但是fork后效率变低)
    • 网卡压力过大。

\

问题:我们可以使用 mem_fragmentation_ratio 来判断 Redis 当前的内存碎片率是否严重,我给出的经验阈值都是大于 1 的。我想请你思考一下,如果 mem_fragmentation_ratio 小于 1,Redis 的内存使用是什么情况呢?会对 Redis 的性能和内存空间利用率造成什么影响呢?

  • mem_fragmentation_ratio(分配内存/实际使用内存) 小于 1,就表明,操作系统分配给 Redis 的内存空间已经小于 Redis 所申请的空间大小了\

  • 会导致频繁的swap

\

问题:在和 Redis 实例交互时,应用程序中使用的客户端需要使用缓冲区吗?如果使用的话,对 Redis 的性能和内存使用会有影响吗?

  • 用程序中使用的 Redis 客户端,需要把要发送的请求暂存在缓冲区\

  • 优点

    • 控制客户端发送请求的频率
    • 应对主从切换导致的无法服务的情况

问题:如何使用慢查询日志和 latency monitor 排查执行慢的操作?

  • Redis 日志(慢查询日志)\

    • slowlog-log-slower-than:这个参数表示,慢查询日志对执行时间大于多少微秒的命令进行记录\

    • slowlog-max-len:这个参数表示,慢查询日志最多能记录多少条命令记录 使用队列 先进先出\

    • SLOWLOG GET 1\

  • latency monitor 来排查执行较慢的命令操作\

    • 设置执行时长 config set latency-monitor-threshold 1000
    • 参看结果 latency latest

问题:如何排查 Redis 的 bigkey?

  • redis-cli 命令时带上–bigkeys 选项,进而对整个数据库中的键值对大小情况进行统计分析\

    • 在从节点执行

    • Redis 实例业务压力的低峰阶段进行扫描查询,以免影响到实例的正常运行\

    • 可以使用 -i 参数控制扫描间隔,避免长时间扫描降低 Redis 实例的性能\

  • 缺陷

    • 只能获取最大的那个 bigkey\

    • 只能统计元素个数

总结

  • 多样的数据结构
  • 如何避免Redis性能变慢

\

\