标签:
当将redis作为缓存服务器时, 需要处理过期缓存问题.
LRU是redis唯一支持的缓存处理方式.
对于缓存方面的设置包括两个参数, 一个是最大缓存数量, 另一个是缓存策略.
参数名为, “maxmemory”, 在配置文件”redis.conf”中设置.
当这个参数设置为0时, 表示内存无限制.
但是对于32位操作系统, 最大内存使用为3GB, 当超过这个数额, 将采取缓存替换策略.
当redis的使用达到上限时, redis将采取回收策略.
redis的回收策略通过”maxmemory-policy”参数的设置.
这个参数可以设置的值为:
当没有键满足回收的条件时, 策略volatile-lru, volatile-random以及volatile-ttl就和noeviction 差不多了。
redis的缓存命中率, 可以通过”RedisINFO”获得.
一般的经验规则:
allkeys-lru 和 volatile-random策略对于当你想要单一的实例实现缓存及持久化一些键时很有用。不过一般运行两个实例是解决这个问题的更好方法。
为了键设置过期时间也是需要消耗内存的,所以使用allkeys-lru这种策略更加高效,因为没有必要为键取设置过期时间当内存有压力时。
redis的LRU算法并不是完整的LRU算法, 只是一种近似的LRU算法.
这种算法对少量的keys进行采样, 然后选择合适键进行淘汰.
redis中有一个参数”maxmemory-samples”可以设置取样的数量.
配合”RedisINFO”可以调试多次, 用于寻找最优的参数设置.
使用MULTI命令开始事务, 使用EXEC命令执行这个事务.
当执行事务时出现错误, 对于2.6以前的版本, redis只执行如对成功的命令.
对于2.6之后的版本, redis会记录执行失败的任务, 当执行EXEC时, 如果队列中出现错误, redis直接放弃这个事务.
redis不支持回滚技术.
DISCARD命令用于清空事务队列中的命令.
WATCH命令可以为redis提供欢乐锁(check-and-set), 在事务中对某个变量设置了欢乐锁,
这个参数被多个进程修改时, 事务将执行失败.
通常用这种方式处理竞争问题.
使用UNWATCH可以取消所有参数的监视.
Redis 提供了不同级别的持久化方式:
除了上面两种持久化方式不同, redis还提供了快照功能.
用户可以设置快照时间或者限定修改次数进行自动快照, 或者使用SAVE和BGSAVE进行快照.
redis有两种不同的分块方式,
一种是3.0之前提供的, 使用Sentinel实现, 这种方式只是一种实验性.
另一种是3.0之后版本提供的, 分片技术.
sentinel工具用于监视redis节点, 然后判断主从情况.
redis支持分片功能, 但是不支持同时处理多个keys问题.
redis集群并没有使用一致性hash, 而是引入哈希槽概念.
Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽.集群的每个节点负责一部分hash槽.
集群中也包含了主从复制模型, 从节点对主节点进行复制, 主节点之间进行分片.
最简单的配置文件:
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
集群的启动至少需要三个主节点, 如果要加入主从复制的功能, 就需要引入至少六个节点, 三个为主节点, 三个为从节点.
为每个节点设置一个配置文件, 用于启动redis.
启动时, 因为nodes.conf不存在, 每个节点会重新分配一个新的ID.
接着使用集群创建脚本创建集群:
redis-trib.rb create --replicas 1 node-list
–replicas参数为备份节点的个数.
redis-trib.rb后面的参数可以分为start, create, stop, reshard, add-node, del-node.
分别用于启动, 创建, 停用集群, 重新分块, 添加节点, 删除节点.
redis常用的数据结构包括:
set,get,decr,incr,mget 等。
String在redis内部存储默认就是一个字符串,被redisObject所引用,当遇到incr,decr等操作时会转成数值型进行计算,此时redisObject的encoding字段为int。
hget,hset,hgetall 等。
第一种方式将用户ID作为查找key,把其他信息封装成一个对象以序列化的方式存储,这种方式的缺点是,增加了序列化/反序列化的开销,并且在需要修改其中一项信息时,需要把整个对象取回,并且修改操作需要对并发进行保护,引入CAS等复杂问题。
第二种方法是这个用户信息对象有多少成员就存成多少个key-value对儿,用用户ID+对应属性的名称作为唯一标识来取得对应属性的值,虽然省去了序列化开销和并发问题,但是用户ID为重复存储,如果存在大量这样的数据,内存浪费还是非常可观的。
上面已经说到Redis Hash对应Value内部实际就是一个HashMap,实际这里会有2种不同实现,这个Hash的成员比较少时Redis为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构,对应的value redisObject的encoding为zipmap,当成员数量增大时会自动转成真正的HashMap,此时encoding为ht。
可以使用下面的参数进行设置
lpush,rpush,lpop,rpop,lrange等。
Redis list的应用场景非常多,也是Redis最重要的数据结构之一,比如twitter的关注列表,粉丝列表等都可以用Redis的list结构来实现,比较好理解,这里不再重复。
Redis list的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,Redis内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。
通过设置下面参数, 用于切换紧凑和实际列表:
sadd,spop,smembers,sunion 等。
Redis set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。
set 的内部实现是一个 value永远为null的HashMap,实际就是通过计算hash的方式来快速排重的,这也是set能提供判断一个成员是否在集合内的原因。
通过设置下面参数, 进行切换紧凑和实际集合:
zadd,zrange,zrem,zcard等
Redis sorted set的使用场景与set类似,区别是set不是自动有序的,而sorted set可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。当你需要一个有序的并且不重复的集合列表,那么可以选择sorted set数据结构,比如twitter 的public timeline可以以发表时间作为score来存储,这样获取时就是自动按时间排好序的。
Redis sorted set的内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,而跳跃表里存放的是所有的成员,排序依据是HashMap里存的score,使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。
标签:
原文地址:http://blog.csdn.net/ghostlv/article/details/51281073