一、键值设计1、键名设计,便于阅读和管理在业务名(或数据库名)前加上前缀(防止键冲突),并用冒号分隔,例如业务名:表名:idugc:video:1在简洁和语义的前提下,控制key的长度。当key很多的时候,内存的占用是不容忽视的。例如:user:{uid}:friends:messages:{mid}简化为u:{uid}:fr:m:{mid}。不包含特殊字符反例:包含空格、换行、单双引号等转义字符2.取值设计拒绝bigkeys,防止网卡流量和慢查询。string类型控制在10KB以内,对hash、list、set、zset等元素个数没有要求。超过5000个。反例:一个有200万个元素的列表。对于非字符串bigkey,不要使用del删除,使用hscan、sscan、zscan逐步删除,同时注意防止bigkey过期时间自动删除(比如设置了200万的zset1小时后过期,会触发del操作,造成Blocking,慢查询中不会出现该操作(latency可勾选)),查找方式和删除方式选择合适的数据类型,如:实体类型(合理控制和使用数据结构内存编码优化配置,如ziplist,但也要注意节省内存和性能的平衡)反例:setuser:1:nametomsetuser:1:age19setuser:1:favorfootball正例:hmsetuser:1nametomage19favourfootball控制键Redis在生命周期中不是垃圾桶。推荐使用expire设置过期时间(如果条件允许可以将过期时间打散,防止集中过期),非过期数据以空闲时间为主。二、命令使用1、O(N)命令注意N的个数,比如hgetall、lrange、smembers、zrange、sinter等也不是不能用,只是需要指定N的值。如果需要遍历,可以使用hscan、sscan、zscan代替。2、禁用keys、flushall、flushdb等禁止在线使用的命令,通过redis的rename机制禁用命令,或者使用scan方式逐步处理。3、selectredis多数据库合理使用薄弱,用数字区分,很多clients支持不好。同时,多服务的多数据库实际上是单线程处理的,会产生干扰。4、使用批处理提高效率原生命令:如mget、mset。非本机命令:可以使用管道来提高效率。但是要注意控制一次批量操作的元素个数(比如500以内,其实和元素字节数有关)。注意两者不同:native是原子操作,pipeline是非原子操作。pipeline可以封装不同的命令,但是nativepipeline不能客户端和服务端都支持。5、不建议过多使用Redis事务功能。Redis的事务功能较弱(不支持回滚),集群版本(自研和官方)要求事务操作的key必须在slot上(可以使用hashtag功能解决)6.Redis集群版本对使用Lua1有特殊要求,所有的key都要通过KEYS数组传递。redis.call/pcall中调用的redis命令,key的位置必须是KEYS数组,否则直接返回错误。使用KEYSarrayrn"2.Allkeysmustbeinoneslot,否则直接返回错误,“-ERReval/evalshacommandkeysmustinsameslotrn”7.monitor命令必要时使用monitor命令,注意不要长时间使用。三、客户端使用1、避免多个应用使用一个Redis实例,服务于公共数据的不相关业务拆分。2、使用连接池可以有效控制连接,同时提高效率。标准使用方法:执行命令如下:jedisjedis=null;试试{jedis=jedisPool.getResource();//具体命令jedis.executeCommand()}catch(Exceptione){logger.error("opkey{}error:"+e.getMessage(),key,e);}finally{//注意这里不是关闭连接。在JedisPool模式下,Jedis会被归还到资源池中。if(jedis!=null)jedis.close();}3、建议客户端在高并发情况下增加熔断功能(如netflixhystrix)4、合理加密设置合理的密码,使用SSL加密访问ifnecessary(阿里云Redis支持)5.淘汰策略根据自己的业务类型,选择maxmemory-policy(最大内存淘汰策略),并设置过期时间。默认策略是volatile-lru,即超过最大内存后,使用lru算法对过期key进行移除,保证非过期数据不会被删除,但可能会出现OOM问题。其他策略如下:allkeys-lru:根据LRU算法删除keys,不管数据是否有超时属性,直到有足够的空间可用。allkeys-random:随机删除所有键,直到有足够的空间。volatile-random:随机删除过期的键,直到有足够的空间。volatile-ttl:根据key-value对象的ttl属性,删除最近即将过期的数据。如果不是,则退回到noeviction策略。noeviction:不会删除任何数据,拒绝所有写操作,并返回客户端错误信息“(error)OOMcommandnotallowedwhenusedmemory”。此时Redis只响应读操作。四、相关工具1、数据同步redis之间的数据同步可以使用:redis-port2、bigkeysearchredis大key搜索工具3、热点key搜索内部实现使用monitor,所以推荐使用facebook的redis-faina阿里云Redis短时间的热键问题已经在内核层面得到解决。五、删除bigkey下面的操作可以使用pipeline进行加速。Redis4.0已经支持异步删除key,欢迎使用。1、哈希删除:hscan+hdelpublicvoiddelBigHash(Stringhost,intport,Stringpassword,StringbigHashKey){Jedisjedis=newJedis(host,port);if(password!=null&&!"".equals(password)){jedis.auth(password);}ScanParamsscanParams=newScanParams().count(100);字符串游标="0";做{ScanResult
