redis使用方式
【cache VS storage】
redis是作为缓存,还是作为存储使用?
1.作为缓存的话,业务方必须为每个key都设置过期时间,并且请注明当redis内存到达配额上限时是否允许key被逐出(默认LRU)
2.作为存储使用,业务方需要考虑数据的清洗策略,否则redis的内存量会一直增长,最终达到上限,导致服务不可用。
对同一套redis的使用,不要出现部分key设置了过期时间,另外部分key没有设置过期时间的情况。
【内存使用量,以及未来的增长趋势如何?】
预计整个业务单份内存量,5GB/10GB/20GB还是更多?未来2年内会增涨到大概多少GB?
redis内存使用量估算方式:(key的平均长度+value的平均长度) * kv个数 * 2
为什么要 乘以 2 ?
redis内存的估算本身很复杂,与key是否设置了过期时间,key的大小,value的类型和大小,value采用的编码和存储方式,redis实例自身垃圾回收的速度,每秒写入量的大小等都相关。所以乘以2是比较保守的估算方式。
对内存资源的评估请本着认真负责的态度,既要能满足业务扩展的需求,又要杜绝资源的浪费。
【qps量,以及未来的增长趋势如何?】
整个redis集群需要提供的qps量,1w、2w还是5w,甚至更多?未来1-2年预估会达到多少?
qps在5000以下的,请优先考虑使用mysql,我们的mysql可以满足绝大部分业务需求,同时提供更好的高可用和数据安全解决方案。对于qps很小(例如只有几百甚至几十的qps),但是业务场景非常适合使用Redis的,请说明具体原因。
【业务使用的命令? KEY设计方式?】
一般redis是由dba来维护的,我们申请redis的时候,业务线要列举用到的命令,这样方便DBA对业务更深入的理解,帮助业务优化和定位问题。
比如:
读命令:get, lrange, hget 等等
写(或读写)命令:setex, set, lpush, lpop 等等
KEY设计方式:给出key的例子,要简短,易懂,比如:key1=user:name**
注:部分高危命令慎用,有些公司会做屏蔽,即使有密码也无法使用,被屏蔽的命令列表参考:
(1)如果命令来自于白名单列表,那么不管是否设置了密码,都跳过密码验证阶段。目的是为了方便dba的管理和兼容之前的各种监控统计脚本,否则改造代价太大。
(2)用户即使提供了密码,也无法使用如下高危命令,除非用户的ip地址在白名单中。也即,在白名单中的ip地址,可以执行如下命令。而不在白名单中的ip,即使提供了密码,也不能使用如下的高危命令:
bgrewriteaof config get config set
config resetstat config rewrite flushall
flushdb shutdown save
bgsave client kill client list
slowlog monitor slaveof
info
【机房部署】
redis需要部署在哪个机房?
是否有跨机房部署需求?我们一般不推荐跨机房部署redis。例如如果前端和业务逻辑都在node1机房,那么推荐redis也部署在node1机房
【是否使用java】
如果dba提供了针对java的客户端,该客户端具有自动sharding、连接池等功能,并通过zookeeper和redis哨兵保证了redis集群的高可用,因此推荐使用dba提供的java client来访问redis.
如果是非java语言,需要访问redis,请另行与dba沟通。
【业务的namespace及业务联系人邮件、邮件组】
namespace需要dba和业务人员共同商定。该名称最好能反映出redis所属的部门,例如支付、无线、酒店等,另外能反映出业务用途,例如qmp_status等.这样方便日后的沟通和问题定位
namespace不要超过20个字符,多个单词用_分隔
单机redis安装
1.安装redis官网:[http://redis.io/download](http://redis.io/download)
可能需要安装make
yum -y install gcc automake autoconf libtool make
安装redis:
$ wget [http://download.redis.io/releases/redis-2.8.17.tar.gz]
$ tar -zxvf redis-2.8.17.tar.gz
$ cd redis-2.8.17
$ make
$ make install
安装完成后,会在redis安装目录下出现一个src文件夹,redis-cli 、redis-server在这个目录下
获取项目中redis信息
1.在项目中引入redis bean
```
<bean id="beanRedis" class="redis client class">
<constructor-arg index="0">
<value>need param</value>
</constructor-arg>
<constructor-arg index="1">
<value>need param</value>
</constructor-arg>
</bean>
```
2.一般公司redis集群信息
clustername ip port timeout coresize maxsize
cluster6399 *.*.*.* 6399 1000 10 40
3.redis-cli获取redis信息
sudo redis-cli -h 127.0.0.1 -p 6399 -a 密码 (ip port 根据自己环境不同)
smembers onekey
4.查看key剩余过期时间
ttl onekey
当 key 不存在时,返回 -2 。
当 key 存在但没有设置剩余生存时间时,返回 -1 。
否则,以秒为单位,返回 key 的剩余生存时间。
在 Redis 2.8 以前,当 key 不存在,或者 key 没有设置剩余生存时间时,命令都返回 -1
项目中遇到的一些bug
1.redis存储与java读取 数据结构不一致
redis中存的string ,取的时候用的对象类型,应该一致
2.java获取缓存数据失败,重新查找接口问题
3.memcached迁移到redis,共存期间,hash算法不一致,导致获取不到数据
缓存测试case参考
场景,老服务A使用memcached ,新服务B使用redis,在迁移过程会有数据共存的现象,这边列出的可能不够详细,仅供参考:
1.redis 读写;
2.数据一致性:B写,A读; A写,B读;
3.容量评估(考虑命中率);
4.超时时间;
5.缓存失效;
等等
网络辟谣
1.关于bind做网络限制的错误解释
bind 127.0.0.1
翻看网上的文章,此处多翻译为“指定redis只接收来自于该IP地址的请求,如果不进行设置,那么将处理所有请求,在生产环境中最好设置该项”。
这种解释会totally搞糊涂初学者,甚至是错误的。该处的英文原文为:
If you want you can bind a single interface, if the bind option is not specified all the interfaces will listen for incoming connections.
bind 127.0.0.1该处说明bind的是interface,也就是说是网络接口。服务器可以有一个网络接口(通俗的说网卡),或者多个。
打个比方说机器上有两个网卡,分别为192.168.205.5 和192.168.205.6,如果bind 192.168.205.5,那么
只有该网卡地址接受外部请求,如果不绑定,则两个网卡口都接受请求。