前言:
有段时间没做技术分享了,这次抽时间给大家分享下redis的高级技巧。 记得两年前在公司做过一场redis的源码实现及设计。 这次想继续这个话题,讲下redis集群的具体实现。 但周边人对这个不敢兴趣,毕竟大家是开发人员,反而对redis应用层的使用更敢兴趣。
我个人接触redis很久了,熟悉我博客的朋友知道,我基本每隔一段时间就会写有关redis的话题。 到现在为止,源码虽然粗略的看过,但也仅限于数据结构及server部分。redis cluster的实现有些复杂,代码看不进去,用同事的话来说,不敢触碰… 这次分享我会尽量把自己的redis使用经验和一些实际的场景分享出来。
分享的pdf 我扔到github了,下载地址: https://github.com/rfyiamcool/share_ppt
https://github.com/rfyiamcool/share_ppt/blob/master/redis_advance.pdf
下面是pdf的几个截图:
内容摘要:
Redis高级讲义 峰云就她了 xiaorui.cc github.com/rfyiamcool key的规范 加入业务的前缀 长度控制在30个字符以内 一级key不要超过千万 同样ziplist类型的hash比strings省内存 Value的规范 选择合适的数据结构 长字符压缩存取 (snappy, msgpack, more...) 避免big key ( 删除和迁移时阻塞) 避免hot key (单点性能) 优化慢请求 避免使用O(n)的指令 (keys *, hgetall, smembers, sunion ...) 使用scan, hscan, sscan, zscan 业务层规避这类设计 提高吞吐 使用pipeline批量传输, 减少网络RTT 使用多值指令 (mset, hmset) 使用script lua 干掉aof ? (big key) or (hot key) big key scan / small range get del > unlink (redis 4.0 async del) hash shard hot key hash shard 不推荐使用命令 pub sub redis transction more ... redis lua 减少RTT消耗 保证多指令原子性 自定义指令 lua 场景 zset的zpop semphore分布式锁 自增id生成器 redis module 注册新指令 性能比redis lua更强劲 redis 4.0 以上 1w 的稳定长连接 9w TPS 队列千万级别 百万数量key 经历过的性能指标 单机进化到多实例 什么是多实例 为什么要多实例化 多实例化需要注意什么? what 多实例 6379 6380 6381 ++ redis1 redis2 redis3 more 最大程度的使用内存 避免单实例RDB时 被kernel oom 使用swap造成阻塞. 单实例启动太慢 扩展, 迁移, 内存随便整理 why 多实例 copy on write will block 绕开redis单工作线程的问题 阻塞指令 busy event hashcrc more ... How 多实例 128G 总内存. 11G 为一个实例, 启动个10实例. 空出18G做缓冲. 后台脚本来触发bgsave. 启动时也是一个个的启动 vip多线程版 twemproxy codis redis cluster 简约集群 codis vs redis cluster cluster y 中心化 client move order y y hash_tag design pipeline slot 多租户 性能 code 范围 high 复杂 广 codis y 去中心化 支持 y y this < cluster 简单 也有不少大厂 redis cluster codis-proxy codis-proxy codis zookeeper redis-m 主机组 redis redis-s redis 使用的高级场景 定时器 去重优先级fifo队列 分布式锁 More ... 定时器 zset (score = timestamp, value=task) sadd zpop Feeds 任务去重 comsumer Feeds lua zpop func comsumer token bucket zset (score = timestamp, value=token) sadd allow burst zpop comsumer Feeds comsumer req rate limiter client True diff_ts := now - ts if diff_ts > period { return wait } return pass prefix period ts prefix counter ts client False 伪ack队列 zset (score = timestamp, value=task) 4. ack pop, ack by lua !!! 1. push producter 3. add in zset list 2. pop comsumer comsumer 去重优先级的FIFO队列 set ( 作为去重特性 ) queue_1 queue_2 queue_3 redis lua 封装增删改查 安全可靠 say no 可重入锁 say yes 公平调度 say hard 分布式锁 lua make ( compare and set ) !!! set + nx + ex client_1 true Redis { bll_lock_key: ident } client_2 set + nx + ex false 排查问题 redis-cli monitor 内部 keyspace slow log 外部 内存碎片 - - bigkeys string, bytes空间 set, list, zset, hash, 元素个数 rdb tool 具体占用空间 监控 info -> instantaneous_ops_per_sec info -> used_memory_human /proc/{pid}/smaps connected_clients 项目分享 https://github.com/rfyiamcool/go_redis_semaphore https://github.com/rfyiamcool/zset_zpop https://github.com/rfyiamcool/redis_unique_queue https://github.com/rfyiamcool/redis_modules_ackqueue https://github.com/rfyiamcool/go_redis_lock https://github.com/rfyiamcool/kvdis other ext redis 多线程方案 去除cow机制的rdb,进化binlog模式 redis rocksdb的持久化方案 more ... “ 别说话 ! ” –峰云就她了
END.