关于redis:面试必备一线大厂Redis设计规范与性能优化
说在后面你是否在应用Redis时,不分明Redis应该遵循的设计规范而苦恼? 你是否在Redis呈现性能问题时,不晓得该如何优化而发愁? 你是否被面试官拷问过Redis的设计规范和性能优化而答复不进去 别慌,看这篇文章就行了 本文,已收录于,我的技术网站 aijiangsir.com,有大厂残缺面经,工作技术,架构师成长之路,等教训分享注释一、Redis Key-Value设计规范&性能优化1. key名设计规范(1)【倡议】: 可读性和可管理性 以业务名(或数据库名)为前缀(避免key抵触),用冒号分隔,比方业务名:表名:id(2)【倡议】:简洁性 保障语义的前提下,管制key的长度,当key较多时,内存占用也不容忽视,例如:(3)【强制】:不要蕴含特殊字符 反例:蕴含空格、换行、单双引号以及其余转义字符2. Value设计规范(1)【强制】:回绝bigkey(避免网卡流量、慢查问) 在Redis中,一个字符串最大512MB,一个二级数据结构(例如hash、list、set、zset)能够存储大概40亿个(2^32-1)个元素,但理论中如果上面两种状况,我就会认为它是bigkey。 字符串类型:它的big体现在单个value值很大,个别认为超过10KB就是bigkey。非字符串类型:哈希、列表、汇合、有序汇合,它们的big体现在元素个数太多。一般来说,string类型管制在10KB以内; hash、list、set、zset元素个数不要超过5000。 反例:一个蕴含200万个元素的list。 3. bigkey性能优化bigkey的危害:导致redis阻塞网络拥塞bigkey也就意味着每次获取要产生的网络流量较大; 假如一个bigkey为1MB,客户端每秒访问量为1000,那么每秒产生1000MB的流量,对于一般的千兆网卡(依照字节算是128MB/s)的服务器来说几乎是灭顶之灾,而且个别服务器会采纳单机多实例的形式来部署,也就是说一个bigkey可能会对其余实例也造成影响,其结果不堪设想。 过期删除有个bigkey,它奉公守法(只执行简略的命令,例如hget、lpop、zscore等),但它设置了过期工夫,当它过期后,会被删除,如果没有应用Redis 4.0的过期异步删除(lazyfree-lazy- expire yes),就会存在阻塞Redis的可能性。bigkey的产生:一般来说,bigkey的产生都是因为程序设计不当,或者对于数据规模意料不分明造成的,来看几个例子: 社交类: 粉丝列表,如果某些明星或者大v不精心设计下,必是bigkey。统计类: 例如按天存储某项性能或者网站的用户汇合,除非没几个人用,否则必是bigkey。缓存类: 将数据从数据库load进去序列化放到Redis里,这个形式十分罕用,但有两个中央须要留神,第一,是不是有必要把所有字段都缓存;第二,有没有相干关联的数据,有的同学为了图不便把相干数据都存一个key下,产生bigkey。如何优化bigkey1、拆 如果是大List(big list),那么就能够拆成多个List:比方拆成:list1、list2、...listN如果是一个大的哈希表(big hash),能够将数据分段存储:比方一个大的key,假如存了1百万的用户数据,能够拆分成 200个key,每个key上面寄存5000个用户数据如果bigkey不可避免,也要思考一下要不要每次把所有元素都取出来(例如有时候仅仅须要 hmget,而不是hgetall),删除也是一样,尽量应用优雅的形式来解决。 2、抉择适合的数据类型【举荐】 最好的优化计划其实是在设计阶段,所以咱们在应用Redis时,在设计阶段就应该尽量避免bigkey,所以抉择适合的数据类型尤为重要。 例如:实体类型(要正当管制和应用数据结构,但也要留神节俭内存和性能质检的均衡) 谬误的做法: 1set user:1:name tom2set user:1:age 193set user:1:favor football正确的做法: hmset user:1 name tom age 19 favor football3、管制key的生命周期,redis不是垃圾桶,当不须要应用的数据,及时过期清理【举荐】 倡议应用Expire设置过期工夫 条件容许能够打散过期工夫,避免几种过期 比方:设置key的过期工夫时,采纳固定过期工夫+肯定范畴内的随机数 二、Redis命令的应用标准&性能优化1、应用O(N)类型的命令要留神关注N的数量【举荐】比方hgetall、lrange、smembers、zrange、sinter等并非不能应用。 然而在应用的时候肯定要明确N的值,不然就可能因为查问数据太大导致redis阻塞。 倡议:有遍历的需要时能够应用hscan、sscan、zscan代替2、生产环境禁用局部高危命令【举荐】禁止线上应用keys、flushall、flushdb等,通过redis的rename机制禁掉命令。 当有须要扫描的须要时,倡议应用scan形式渐进式解决3、正当应用select【举荐】redis的多数据库较弱,应用数字进行辨别,很多客户端反对较差,同时多业务用多数据库理论还是单线程解决,会有烦扰 所以倡议redis应用数据库只用序号0的数据库即可,在0数据库里采纳key前缀辨别业务即可4、应用批量操作提高效率【举荐】当咱们要插入多个key时,能够采纳一些批量命令代替单个命令,进步查问效率,例如: 1原生命令:例如mget、mset。2非原生命令:能够应用pipeline提高效率。但要留神管制一次批量操作的元素个数(例如500以内,理论也和元素字节数无关)。 留神两者不同: 11. 原生命令是原子操作,pipeline是非原子操作。22. pipeline能够打包不同的命令,原生命令做不到33. pipeline须要客户端和服务端同时反对。5、redis事务性能较弱,不倡议过多应用redis的事务命令如果业务上有须要,能够应用lua代替【倡议】 三、客户端应用标准&性能优化1、防止多个利用应用同一个Redis实例【举荐】谬误的做法: 多个业务线专用同一个redis实例,比方订单、库存、权限都用同一个redis实例,只有有一块业务有阻塞,所有业务都会受影响。 正确的做法: 不相干的业务拆分为独立的redis实例,比方订单、库存、权限拆分为3个redis实例。 ...