redis开发与运维

1. 初识redis

redis的8个特性:速度快、基于键值对的数据结构服务器、功能丰富、简单稳定、客户端语言多、持久化、主从复制、支持高可用和分布式。
    redis不是万金油,有些场景不符合redis
    开发运维结合以及阅读源码
    生产环境中使用配置文件启动redis
    Redis3.0是重要的里程碑, 发布了Redis官方的分布式实现Redis Cluster。

2. API的理解和使用

Redis提供5种数据结构, 每种数据结构都有多种内部编码实现。
    纯内存存储、 IO多路复用技术、 单线程架构是造就Redis高性能的三个因素。
    因为Redis的单线程架构, 因此须要每一个命令能被快速执行完, 不然会存在阻塞Redis的可能, 理解Redis单线程命令处理机制是开发和运维Redis的核心之一。
    批量操做(例如mget、 mset、 hmset等) 可以有效提升命令执行的效率, 但要注意每次批量操做的个数和字节数。
    了解每一个命令的时间复杂度在开发中相当重要, 例如在使用keys、 hgetall、 smembers、 zrange等时间复杂度较高的命令时,须要考虑数据规模对于Redis的影响。
    persist命令能够删除任意类型键的过时时间, 可是set命令也会删除字符串类型键的过时时间, 这在开发时容易被忽视。
    move、 dump+restore、 migrate是Redis发展过程当中三种迁移键的方式, 其中 move命令基本废弃, migrate命令用原子性的方式实现了dump+restore, 而且支持批量操做, 是Redis Cluster实现水平扩容的重要工具。
    scan命令能够解决keys命令可能带来的阻塞问题, 同时Redis还提供了hscan、 sscan、 zscan渐进式地遍历hash、 set、 zset。

3. 小功能大用处

慢查询中的两个重要参数slowlog-log-slower-than和slowlog-max-len。
    慢查询不包含命令网络传输和排队时间。
    有必要将慢查询按期存放。
    redis-cli一些重要的选项, 例如--latency、 –-bigkeys、 -i和-r组合。
    redis-benchmark的使用方法和重要参数。
    Pipeline能够有效减小RTT次数, 但每次Pipeline的命令数量不能无节制。
    Redis可使用Lua脚本创造出原子、 高效、 自定义命令组合。
    Redis执行Lua脚本有两种方法: eval和evalsha。
    Bitmaps能够用来作独立用户统计, 有效节省内存。
    Bitmaps中setbit一个大的偏移量, 因为申请大量内存会致使阻塞。
    HyperLogLog虽然在统计独立总量时存在必定的偏差, 可是节省的内存量十分惊人。
    Redis的发布订阅机制相比许多专业的消息队列系统功能较弱, 不具有堆积和回溯消息的能力, 但胜在足够简单。
    Redis3.2提供了GEO功能, 用来实现基于地理位置信息的应用, 但底层实现是zset。

4. 客户端

RESP(Redis Serialization Protocol Redis) 保证客户端与服务端的正常通讯, 是各类编程语言开发客户端的基础。
    要选择社区活跃客户端, 在实际项目中使用稳定版本的客户端。
    区分Jedis直连和链接池的区别, 在生产环境中, 应该使用链接池。
    Jedis.close() 在直连下是关闭链接, 在链接池则是归还链接。
    Jedis客户端没有内置序列化, 须要本身选用。
    客户端输入缓冲区不能配置, 强制限制在1G以内, 可是不会受到maxmemory限制。
    客户端输出缓冲区支持普通客户端、 发布订阅客户端、 复制客户端配置, 一样会受到maxmemory限制。
    Redis的timeout配置能够自动关闭闲置客户端, tcp-keepalive参数能够周期性检查关闭无效TCP链接
    monitor命令虽然好用, 可是在大并发下存在输出缓冲区暴涨的可能性。
    info clients帮助开发和运维人员找到客户端可能存在的问题。
    理解Redis通讯原理和创建完善的监控系统对快速定位解决客户端常见问题很是有帮助。

5. 持久化

Redis提供了两种持久化方式: RDB和AOF。
    RDB使用一次性生成内存快照的方式, 产生的文件紧凑压缩比更高, 所以读取RDB恢复速度更快。 因为每次生成RDB开销较大, 没法作到实时持久化, 通常用于数据冷备和复制传输。
    save命令会阻塞主线程不建议使用, bgsave命令经过fork操做建立子进程生成RDB避免阻塞。
    AOF经过追加写命令到文件实现持久化, 经过appendfsync参数能够控制实时/秒级持久化。 由于须要不断追加写命令, 因此AOF文件体积逐渐变大, 须要按期执行重写操做来下降文件体积。
    AOF重写能够经过auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数控制自动触发, 也可使用bgrewriteaof命令手动触发。
    子进程执行期间使用copy-on-write机制与父进程共享内存, 避免内存消耗翻倍。 AOF重写期间还须要维护重写缓冲区, 保存新的写入命令避免数据丢失。
    持久化阻塞主线程场景有: fork阻塞和AOF追加阻塞。 fork阻塞时间跟内存量和系统有关, AOF追加阻塞说明硬盘资源紧张。
    单机下部署多个实例时, 为了防止出现多个子进程执行重写操做, 建议作隔离控制, 避免CPU和IO资源竞争。

6. 复制

Redis经过复制功能实现主节点的多个副本。 从节点可灵活地经过slaveof命令创建或断开复制流程。
    复制支持树状结构, 从节点能够复制另外一个从节点, 实现一层层向下的复制流。 Redis2.8以后复制的流程分为: 全量复制和部分复制。 全量复制须要同步所有主节点的数据集, 大量消耗机器和网络资源。 而部分复制有效减小因网络异常等缘由形成的没必要要全量复制状况。 经过配置合理的复制积压缓冲区尽可能避免全量复制。
    主从节点之间维护心跳和偏移量检查机制, 保证主从节点通讯正常和数据一致
    Redis为了保证高性能复制过程是异步的, 写命令处理完后直接返回给客户端, 不等待从节点复制完成。 所以从节点数据集会有延迟状况。
    当使用从节点用于读写分离时会存在数据延迟、 过时数据、 从节点可用性等问题, 须要根据自身业务提早做出规避。
     在运维过程当中, 主节点存在多个从节点或者一台机器上部署大量主节点的状况下, 会有复制风暴的风险。

7. redis的噩梦:阻塞

客户端最早感知阻塞等Redis超时行为, 加入日志监控报警工具可快速定位阻塞问题, 同时须要对Redis进程和机器作全面监控。
    阻塞的内在缘由: 确认主线程是否存在阻塞, 检查慢查询等信息, 发现不合理使用API或数据结构的状况, 如keys、 sort、 hgetall等。 关注CPU使用率防止单核跑满。 当硬盘IO资源紧张时, AOF追加也会阻塞主线程。
    阻塞的外在缘由: 从CPU竞争、 内存交换、 网络问题等方面入手排查是否由于系统层面问题引发阻塞。

8. 理解内存

Redis实际内存消耗主要包括: 键值对象、 缓冲区内存、 内存碎片。
    经过调整maxmemory控制Redis最大可用内存。 当内存使用超出时, 根据maxmemory-policy控制内存回收策略。
    内存是相对宝贵的资源, 经过合理的优化能够有效地下降内存的使用量, 内存优化的思路包括:
        精简键值对大小, 键值字面量精简, 使用高效二进制序列化工具。
        使用对象共享池优化小整数对象。
        数据优先使用整数, 比字符串类型更节省空间。
        优化字符串使用, 避免预分配形成的内存浪费
        使用ziplist压缩编码优化hash、 list等结构, 注重效率和空间的平衡。
        使用intset编码优化整数集合。
        使用ziplist编码的hash结构下降小对象链规模。

9. 哨兵

Redis Sentinel是Redis的高可用实现方案: 故障发现、 故障自动转移、 配置中心、 客户端通知。
    Redis Sentinel从Redis2.8版本开始才正式生产可用, 以前版本生产不可用。
    尽量在不一样物理机上部署Redis Sentinel全部节点。
    Redis Sentinel中的Sentinel节点个数应该为大于等于3且最好为奇数。
    Redis Sentinel中的数据节点与普通数据节点没有区别。
    客户端初始化时链接的是Sentinel节点集合, 再也不是具体的Redis节点, 但Sentinel只是配置中心不是代理。
    Redis Sentinel经过三个定时任务实现了Sentinel节点对于主节点、 从节点、 其他Sentinel节点的监控。
    Redis Sentinel在对节点作失败断定时分为主观下线和客观下线。
    看懂Redis Sentinel故障转移日志对于Redis Sentnel以及问题排查很是有帮助。
    Redis Sentinel实现读写分离高可用能够依赖Sentinel节点的消息通知, 获取Redis数据节点的状态变化。

10. 集群

相关文章
相关标签/搜索