• Redis 开发规范手册


    一、  数据库选型

    【建议】首先判断业务类型是否必须使用Redis存储数据,能否使用传统关系性数据库解决。使用Redis提前做好容量规划,注意数据冷热分离,避免将全部数据加载到Redis中。例如:

    l   根据业务类型,选择合适的最大内存及淘汰策略,设置好Key过期时间

     

    二、  Key命名

    Redis有两层(key-value)或三层(key-field-value)结构,通常良好的Key命名习惯会为日常的开发和运维工作带来极大的便利性。

    2.1     可读性

    【建议】可读性高的Key命名有助于排查线上问题、方便的进行批量处理。建议使用业务名称加冒号分割命名,"业务名/数据库名:表名:id"作为前缀,key的长度不超过100个字符。例如:

    l   当前redis内存暴涨,通过高频key前缀可以轻易的区分出是哪个系统的哪个模块在频繁操作,快速定位问题。

    l   当定位到线上问题时,可以通过模式匹配批量处理该类Key。

    2.2     简洁性

    【建议】因为Redis中存储的Key数量可能非常庞大,在保证可读性的前提下,可以适当缩短Key的长度,以减小内存开销。例如:

    l   建议key命名在64字符以内,在越庞大的系统中效果越明显。

    原Key:

    userid:{uid}:friends:messagesid:{mid}

    缩短后的Key,至少降低10字节的空间:

    uid:{uid}:friends:mid:{mid}

    2.3     规范性

    【强制】Key命名需强制遵守以下规范,例如:

    l   禁止包含特殊字符。例如:空格、换行、单双引号以及其他转义字符

    l   满足业务需要的情况下,尽量合理设置Key过期时间,建议过期时间打散,防止集中过期,并且越短越好

    原Key:

    redis> SET "userid:1:name" "Tom"  EX 90

    redis> SET "userid:2:name" "Jack"  EX 90

    redis> SET "userid:3:name" "Bob"  EX 90

    优化过期时间后的Key:

    redis> SET "userid:1:name" "Tom"  PX 60100

    redis> SET "userid:2:name" "Jack"  PX 60200

    redis> SET "userid:3:name" "Bob"  PX 60300

     

    三、  Value设计

    如果说Key规范命名极大的提高了开发运维的便利性,那么Value设计规范更大的增加了Redis运行的高性能和可靠性

    3.1     数据类型

    【建议】Redis相比其它内存型数据库具有更加丰富的数据类型可供应用选择。例如:

    l   Strings类型: 单个kv存储、适用于如简单计数等。

    l   Hash类型: 多个相关属性放到一个Hash中、适用于如存储对象。

    l   Set类型: 集合类型、适用于如归类对象等

    l   Sorted Set类型: 有序集合类型、适用于如榜单排行

    l   Lists类型: 队列类型、适用于如队列、粉丝/关注列表等

    l   特殊的数据类型:Hyperloglog、Geo、Scripting,需要提前跟DBA沟通

    3.2     Bigkey

    【强制】禁止Redis中出现Bigkey,防止出现高并发下网络拥堵、阻塞超时发生切换、集群内存空间不均衡、过期删除、迁移困难及慢查询。例如:

    l   string类型控制在10KB以内,hash、list、set、zset元素个数不要超过5000(实际需要观察元素的字节数),建议压缩后存储

    l   非字符串的bigkey,不要使用del删除,使用hscan、sscan、zscan方式渐进式删除

    l   注意bigkey过期时间,过期后会自动触发del造成阻塞,并且该del不会记录到慢查询

    3.3     定长更新

    【建议】因为Redis内存使用具有预分配和惰性删除的特性,因此Value内容的长度频繁变化极易导致Redis内存碎片的产生。内存碎片风险如下:

    l   当内存碎片较多时,会导致取少量数据扫描大量内存块,严重拖慢Redis的运行

    l   目前Redis内存碎片回收方式较困难,基本需要重启Redis实例才能释放碎片

     

    四、  Redis安全

    4.1   运行安全

    【强制】防止Redis运行期间发生阻塞、崩溃、被入侵

    l   Redis务必配置复杂度高的访问密码(requirepass、masterauth),64位以上,防止暴力破解

    l   避免用root用户启动

    l   禁止测试环境连接与生产环境混用

    l   禁止压测生产环境

    l   禁止存储图片、音频、视频、文件等大数据

    l   禁止不同业务使用相同Redis实例

    l   优先选择Redis 4.0.14版本,若对高版本功能有需要,也可选择Redis 5.0.5版本

    l   Redis单实例物理内存占用尽量保持在10G,最大不要超过20G

    4.2   使用安全

    l   高风险命令

    【强制】数据清除:flushall、flushdb建议在Redis中禁用

    【建议】Server运行:shutdown、monitor、config、save、bgsave、bgrewriteaof建议在Redis中rename-command

    【建议】易阻塞:关注时间复杂度O(N)的命令:keys、smembers、lrange、hgetall、sinter等,使用时明确N的值。有遍历的需求可以使用hscan、sscan、zscan代替并在客户端进行去重。此外,del bigkey、flushdb/flushall删除大量数据时,也会造成Redis短时间阻塞。Redis 4.0版本推出后台异步删除的方式(UNLINK、flushdb/flushall async)来避免该情况

    l   特性功能

    【建议】select:Redis实例虽然支持多个库,但因为Redis是单线程架构,同时多个业务使用多个库仍然会相互干扰

    【建议】批量操作提高效率:Redis原生支持mget、mset、hmset等命令批量操作,非原生批量操作可以使用pipline提高效率,注意一次批量操作的元素个数不要太多,最好在100以内,以实际元素字节数大小为准

    n   原生命令为原子操作,pipline可以打包多个命令但为非原子操作

    n   pipline需要客户端于服务端同时支持

    【建议】事务:Redis事务功能支持较弱,不建议过多使用

    【建议】消息队列:Redis List常被用作消息队列服务。因为功能相对简单,不支持消息重传、持久化等功能,当消费者崩溃时可能导致数据丢失。因此对于要求消息可靠性高的场景,建议使用更加专业的MQ软件

    【建议】Redis cluster限制:

    n   只支持具有相同slot值的key执行批量操作

    n   一次事务操作的Key必须在一个slot中,可以hash tag实现定向分片(当一个key包含 {} 的时候,就不对整个key做hash,而仅对{}包括的字符串做hash)。

    n   key是数据分区的最小粒度,因此不能将一个大的键值对象,如hash,list等映射到不同的节点上

    n   不支持多数据库,只能使用默认的0号库

    n   不能使用级联复制

     

    五、  集群架构

    【强制】Redis高可用相关规范

    l   禁止将线下节点复制到线上主库

    l   主从集群必须配置哨兵高可用

    l   线上业务禁止使用级联架构

    l   Redis Cluster集群架构至少三个分片

    l   主从节点版本必须保持一致

     

    六、  客户端

    【建议】Redis客户端相关规范

    l   使用带有连接池的客户端控制连接,提高通信效率。常用客户端比如Jedis、lettuce、Redisson

    l   对于特别重要的数据、连接相关的操作需要保证捕获异常,防止错误被淹没、数据操作状态不确定

    l   高并发下建议客户端添加熔断功能

  • 相关阅读:
    ubuntu下文件安装与卸载
    webkit中的JavaScriptCore部分
    ubuntu 显示文件夹中的隐藏文件
    C语言中的fscanf函数
    test
    Use SandCastle to generate help document automatically.
    XElement Getting OuterXML and InnerXML
    XUACompatible meta 用法
    Adobe Dreamweaver CS5.5 中文版 下载 注册码
    The Difference Between jQuery’s .bind(), .live(), and .delegate()
  • 原文地址:https://www.cnblogs.com/l10n/p/13753398.html
Copyright © 2020-2023  润新知