1.基础理解:
string 字符串(能够为整形、浮点型和字符串,统称为元素)
list 列表(实现队列,元素不惟一,先入先出原则)
set 集合(各不相同的元素)
hash hash散列值(hash的key必须是惟一的)
sort set 有序集合
html
2.全部命令:http://redisdoc.com/web
——————————————————————————————————————————————————————————————————————————————————————————————————redis
(1).string类型的经常使用命令:它可以存储任何类型的字符串,包含二进制数据。能够用于存储邮箱,JSON化的对象,甚至是一张图片,一个字符串容许存储的最大容量为512MB。
SET key value SET 赋值;
SETNX key value 若是key不存在则赋值,若是key存在不赋值;
SETEX key timeout value 设置KEY的过时时间
GET key GET 取值;
INCR key INCR 递增数字,仅仅对数字类型的键有用,至关于Java的i++运算;
INCRBY key increment INCRBY 增长指定的数字,仅仅对数字类型的键有用,至关于Java的i+=3,increment能够为负数,表示减小;
DECR key DECR 递减数字,仅仅对数字类型的键有用,至关于Java的i––;
DECRBY key decrement DECRBY 减小指定的数字,仅仅对数字类型的键有用,至关于Java的i-=3,decrement能够为正数,表示增长;
INCRBYFLOAT key increment INCRBYFLOAT 增长指定浮点数,仅仅对数字类型的键有用;
APPEND key value APPEND 向尾部追加值,至关于Java中的”hello”.append(“ world”);
STRLEN key STRLEN 获取字符串长度;
MSET key1 value1 [key2 value2 ...] MSET 同时设置多个key的值;
MGET key1 [key2 ...] MGET 同时获取多个key的值;数据库
位操做
GETBIT key offset GETBIT获取一个键值的二进制位的指定位置的值(0/1);
SETBIT key offset value SETBIT设置一个键值的二进制位的指定位置的值(0/1);
BITCOUNT key [start end] BITCOUNT 获取一个键值的一个范围内的二进制表示的1的个数;
BITOP OP desKey key1 key2 BITOP 该命令能够对多个字符串类型键进行位运算,并将结果存储到指定的键中,BITOP支持的运算包含:OR,AND,XOR,NOT;
BITPOS key 0/1 [start, end] BITPOS 获取指定键的第一个位值为0或者1的位置;vim
(2).list:
列表类型(list)用于存储一个有序的字符串列表,经常使用的操做是向队列两端添加元素或者得到列表的某一片断。列表内部使用的是双向链表(double linked list)实现的,因此向列表两端添加元素的时间复杂度是O(1),获取越接近列表两端的元素的速度越快。可是缺点是使用列表经过索引访问元素的效率过低(须要从端点开始遍历元素)。因此列表的使用场景通常如:朋友圈新鲜事,只关心最新的一些内容。借助列表类型,Redis还能够做为消息队列使用。api
查询:
1.lindex [lindex key index]:经过索引index获取列表的元素、key>=0从头至尾,key<0从尾到头
2.lrange [lrange key range_l range_r]:0 表头、-1表尾缓存
增长:
1.lpush [lpush key valus...] 相似于压栈操做,将元素放入头部
2.lpushx [lpushx key valus]:只能插入已经存在的key,且一次只能插入一次
3.rpush [rpush key valus...] :将元素push在list的尾部
4.rpushx [rpushx key valus...] :相对于lpushx
5.linsert [linsert key before/after pivot value]:将值插入到pivot的前面或后面。返回列表元素个数。若是参照点pivot不存在不插入。若是有多个pivot,以离表头最近的为准ruby
删除:
1.lpop 、rpop:分别为删除头部和尾部,返回被删除的元素
2.ltrim [ltrim key range_l range_r]:保留区域类的元素,其余的删除
3.lrem [lrem key count value] :移除等于value的元素,当count>0时,从表头开始查找,移除count个;当count=0时,从表头开始查找,移除全部等于value的;当count<0时,从表尾开始查找,移除|count| 个服务器
修改:
1.lset [lset key index value] : 设置列表指定索引的值,若是指定索引不存在则报错数据结构
RPOPLPUSH source destination 将元素从一个列表转义到另外一个列表;
(3).set类型支持的经常使用命令:集合在概念在高中课本就学过,集合中每一个元素都是不一样的,集合中的元素个数最多为2的32次方-1个,集合中的元素是没有顺序的。
SADD key value1 [value2 value3 ...] 添加元素;
SREM key value2 [value2 value3 ...] 删除元素;
SMEMBERS key 得到集合中全部元素;
SISMEMBER key value 判断元素是否在集合中;
SDIFF key1 key2 [key3 ...] 对集合作差集运算,先计算key1和key2的差集,而后再用结果与key3作差集;
SINTER key1 key2 [key3 ...] 对集合作交集运算;
SUNION key1 key2 [key3 ...] 对集合作并集运算;
SCARD key 得到集合中元素的个数;
SPOP key 从集合中随机弹出一个元素;
SDIFFSTORE destination key1 key2 [key3 ...] 对集合作差集并将结果存储在destination;
SINTERSTORE destination key1 key2 [key3 ...] 对集合作交集运算并将结果存储在destination;
SUNIONSTORE destination key1 key2 [key3 ...] 对集合作并集运算并将结果存储在destination;
SRANDMEMBER key [count] 随机获取集合中的元素,当count>0时,会随机中集合中获取count个不重复的元素,当count<0时,随机中集合中获取|count|和可能重复的元素。
SMOVE source destination member 将 member 元素从 source 集合移动到 destination 集合
(4).hash数据类型支持的经常使用命令:
散列类型至关于Java中的HashMap,他的值是一个字典,保存不少key,value对,每对key,value的值个键都是字符串类型,换句话说,散列类型不能嵌套其余数据类型。一个散列类型键最多能够包含2的32次方-1个字段。
HDEL key field [field2] 删除一个或多个哈希表字段
HEXISTS key field 查看哈希表 key 中,指定的字段是否存在, 返回0 || 1
HGET key field 获取存储在哈希表中指定字段的值
HGETALL key 获取在哈希表中指定 key 的全部字段和值
HINCRBY key field increment 为哈希表 key 中的指定字段的整数值加上增量 increment
HINCRBYFLOAT key field increment 为哈希表 key 中的指定字段的浮点数值加上增量 increment
HKEYS key 获取全部哈希表中的字段
HLEN key 获取哈希表中字段的数量
HMGET key field1 [field2] 获取全部给定字段的值
HMSET key field1 value1 [ field2 value2 ]同时将多个 field-value (域-值)对设置到哈希表 key 中
HSET key field value将哈希表 key 中的字段 field 的值设为 value
HSETNX key field value只有在字段 field 不存在时,设置哈希表字段的值
HVALS key 获取哈希表中全部值
HSCAN key cursor [MATCH pattern] [COUNT count] 迭代哈希表中的键值对
(5).sort set:有序集合类型与集合类型的区别就是他是有序的。有序集合是在集合的基础上为每个元素关联一个分数,这就让有序集合不只支持插入,删除,判断元素是否存在等操做外,还支持获取分数最高/最低的前N个元素。有序集合中的每一个元素是不一样的,可是分数却能够相同。有序集合使用散列表和跳跃表实现,即便读取位于中间部分的数据也很快,时间复杂度为O(log(N)),有序集合比列表更费内存。
ZADD key score1 value1 [score2 value2 score3 value3 ...] 添加元素;
ZSCORE key value 获取元素的分数;
ZRANGE key start stop [WITHSCORE] 获取排名在某个范围的元素,按照元素从小到大的顺序排序,从0开始编号,包含start和stop对应的元素,WITHSCORE选项表示是否返回元素分数;
ZREVRANGE key start stop [WITHSCORE] 获取排名在某个范围的元素,和上一个命令用法同样,只是这个倒序排序的;
ZRANGEBYSCORE key min max 获取指定分数范围内的元素,包含min和max,(min表示不包含min,(max表示不包含max,+inf表示无穷大;
ZINCRBY key increment value 增长某个元素的分数;
ZCARD key 获取集合中元素的个数;
ZCOUNT key min max 返回有序集 key 中, score 值在 min 和 max 之间(默认包括 score 值等于 min 或 max )的成员的数量
ZREM key value1 [value2 ...] 删除一个或多个元素;
ZREMRANGEBYRANK key start stop 按照排名范围删除元素;
ZREMRANGEBYSCORE key min max 按照分数范围删除元素;
ZRANK key value 获取正序排序的元素的排名;
ZREVRANK key value 获取逆序排序的元素的排名;
ZINTERSTORE destination numbers key1 key2 [key3 key4 ...] WEIGHTS weight1 weight2 [weight3 weight4 ...] AGGREGATE SUM | MIN | MAX 计算有序集合的交集并存储结果,numbers表示参加运算的集合个数,weight表示权重,aggregate表示结果取值;
ZUNIONSTORE 计算有序几个的并集并存储结果,用法和上面同样;
zadd的理解: 将一个或多个 member 元素及其 score 值加入到有序集 key 当中。若是某个 member 已是有序集的成员,那么更新这个 member 的 score 值,并经过从新插入这个 member 元素,来保证该 member 在正确的位置上。score 值能够是整数值或双精度浮点数。若是 key 不存在,则建立一个空的有序集并执行 ZADD 操做。当 key 存在但不是有序集类型时,返回一个错误。
(6).其余经常使用命令:
1.Redis删除某个数据库中以某个字符开头的key
redis-cli -n 9 keys "c_recom" | xargs redis-cli -n 9 del
redis-cli -h 10.132.3.213 -p 6379 -a 888k6 -n 4 keys “ecard” | xargs redis-cli -h 10.132.3.213 -p 6379 -a 888k6 -n 4 del
2.键值相关命令
type key 查看key类型
keys * 查看全部key
exists key 查看是否有这个key
del key 删除key
expire key 100 设置key100秒生存期
ttl key 获取key的有效时长 [-1存在未设置 -2不存在] ,返回 key 的剩余生存时间
select 0 选择到0数据库 [ redis默认的数据库是0~15一共16个数据库 ]
move key 1 将当前数据库中的key移动到其余的数据库[ 数据库1 ]
persist key 移除key的过时时间
randomkey 随机返回数据库里面的一个key
rename key2 key3 重命名key2 为key3
3.服务器相关命令
ping PONG 返回响应是否链接成功
echo 在命令行打印一些内容
select 0~15 编号的数据库
quit || exit 退出客户端
dbsize 返回当前数据库中全部key的数量
info 返回redis的相关信息
config get dir/* 实时传储收到的请求
flushdb 删除当前选择数据库中的全部key
flushall 删除全部数据库中的数据库
4.info http://redisdoc.com/server/info.html
memory相关:
used_memory : 由 Redis 分配器分配的内存总量,以字节(byte)为单位
used_memory_human : 以人类可读的格式返回 Redis 分配的内存总量
used_memory_rss : 从操做系统的角度,返回 Redis 已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps 等命令的输出一致。
used_memory_peak : Redis 的内存消耗峰值(以字节为单位)
used_memory_peak_human : 以人类可读的格式返回 Redis 的内存消耗峰值
used_memory_lua : Lua 引擎所使用的内存大小(以字节为单位)
mem_fragmentation_ratio : used_memory_rss 和 used_memory 之间的比率
mem_allocator : 在编译时指定的, Redis 所使用的内存分配器。能够是 libc 、 jemalloc 或者 tcmalloc 。
在理想状况下, used_memory_rss 的值应该只比 used_memory 稍微高一点儿。
当 rss > used ,且二者的值相差较大时,表示存在(内部或外部的)内存碎片。
内存碎片的比率能够经过 mem_fragmentation_ratio 的值看出。
当 used > rss 时,表示 Redis 的部份内存被操做系统换出到交换空间了,在这种状况下,操做可能会产生明显的延迟。
Because Redis does not have control over how its allocations are mapped to memory pages, high used_memory_rss is often the result of a spike in memory usage.
当 Redis 释放内存时,分配器可能会,也可能不会,将内存返还给操做系统。
若是 Redis 释放了内存,却没有将内存返还给操做系统,那么 used_memory 的值可能和操做系统显示的 Redis 内存占用并不一致。
查看 used_memory_peak 的值能够验证这种状况是否发生。
5.启动&关闭
启动
/usr/local/Cellar/redis/3.2.5/bin/redis-server /usr/local/etc/redis.conf
[ redis-server /usr/local/etc/redis.conf ]
redis指定配置文件启动
vim /usr/local/etc/redis.conf
daemonize no(默认),改为 yes,意思是是否要后台启动。
关闭
不能用 kill 暴力关闭,由于可能会丢失数据,
使用./redis-cli shutdown,redis 会先保存好数据,再关闭
——————————————————————————————————————————————————————————————————————————————————————————————
String
String数据结构是简单的key-value类型,value其实不只能够是String,也能够是数字。
常规key-value缓存应用;
常规计数:微博数,粉丝数等。
hash
Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。
存储部分变动的数据,如用户信息等。
list
list就是链表,略有数据结构知识的人都应该能理解其结构。使用Lists结构,咱们能够轻松地实现最新消息排行等功能。List的另外一个应用就是消息队列,能够利用List的PUSH操做,将任务存在List中,而后工做线程再用POP操做将任务取出进行执行。Redis还提供了操做List中某一段的api,你能够直接查询,删除List中某一段的元素。
Redis的list是每一个子元素都是String类型的双向链表,能够经过push和pop操做从列表的头部或者尾部添加或者删除元素,这样List便可以做为栈,也能够做为队列。
消息队列系统
使用list能够构建队列系统,使用sorted set甚至能够构建有优先级的队列系统。
好比:将Redis用做日志收集器
实际上仍是一个队列,多个端点将日志信息写入Redis,而后一个worker统一将全部日志写到磁盘。
取最新N个数据的操做
//把当前登陆人添加到链表里
ret = r.lpush("login:last_login_times", uid)
//保持链表只有N位
ret = redis.ltrim("login:last_login_times", 0, N-1)
//得到前N个最新登录的用户Id列表
last_login_list = r.lrange("login:last_login_times", 0, N-1)
好比sina微博:
在Redis中咱们的最新微博ID使用了常驻缓存,这是一直更新的。可是作了限制不能超过5000个ID,所以获取ID的函数会一直询问Redis。只有在start/count参数超出了这个范围的时候,才须要去访问数据库。
系统不会像传统方式那样“刷新”缓存,Redis实例中的信息永远是一致的。SQL数据库(或是硬盘上的其余类型数据库)只是在用户须要获取“很远”的数据时才会被触发,而主页或第一个评论页是不会麻烦到硬盘上的数据库了。
set
set就是一个集合,集合的概念就是一堆不重复值的组合。利用Redis提供的set数据结构,能够存储一些集合性的数据。set中的元素是没有顺序的。
案例:
在微博应用中,能够将一个用户全部的关注人存在一个集合中,将其全部粉丝存在一个集合。Redis还为集合提供了求交集、并集、差集等操做,能够很是方便的实现如共同关注、共同喜爱、二度好友等功能,对上面的全部集合操做,你还可使用不一样的命令选择将结果返回给客户端仍是存集到一个新的集合中。
交集,并集,差集
//book表存储book名称
set book:1:name "The Ruby Programming Language"
set book:2:name "Ruby on rail"
set book:3:name "Programming Erlang"
//tag表使用集合来存储数据,由于集合擅长求交集、并集
sadd tag:ruby 1
sadd tag:ruby 2
sadd tag:web 2
sadd tag:erlang 3
//即属于ruby又属于web的书?
inter_list = redis.sinter("tag:web", "tag:ruby")
//即属于ruby,但不属于web的书?
diff_list = redis.sdiff("tag:ruby", "tag:web")
//属于ruby和属于web的书的合集?
union_list = redis.sunion("tag:ruby", "tag:web")
获取某段时间全部数据去重值
这个使用Redis的set数据结构最合适了,只须要不断地将数据往set中扔就好了,set意为集合,因此会自动排重。
sorted set
和set相比,sorted set增长了一个权重参数score,使得集合中的元素可以按score进行有序排列,好比一个存储全班同窗成绩的sorted set,其集合value能够是同窗的学号,而score就能够是其考试得分,这样在数据插入集合的时候,就已经进行了自然的排序。能够用sorted set来作带权重的队列,好比普通消息的score为1,重要消息的score为2,而后工做线程能够选择按score的倒序来获取工做任务。让重要的任务优先执行。
排行榜应用,取TOP N操做
这个需求与上面需求的不一样之处在于,前面操做以时间为权重,这个是以某个条件为权重,好比按顶的次数排序,这时候就须要咱们的sorted set出马了,将你要排序的值设置成sorted set的score,将具体的数据设置成相应的value,每次只须要执行一条ZADD命令便可。
//将登陆次数和用户统一存储在一个sorted set里
zadd login:login_times 5 1
zadd login:login_times 1 2
zadd login:login_times 2 3
//当用户登陆时,对该用户的登陆次数自增1
ret = r.zincrby("login:login_times", 1, uid)
//那么如何得到登陆次数最多的用户呢,逆序排列取得排名前N的用户
ret = r.zrevrange("login:login_times", 0, N-1)
好比在线游戏的排行榜,根据得分你一般想要:
- 列出前100名高分选手 - 列出某用户当前的全球排名
这些操做对于Redis来讲小菜一碟,即便你有几百万个用户,每分钟都会有几百万个新的得分。
模式是这样的,每次得到新得分时,咱们用这样的代码:
ZADD leaderboard
你可能用userID来取代username,这取决于你是怎么设计的。
获得前100名高分用户很简单:
ZREVRANGE leaderboard 0 99
用户的全球排名也类似,只须要:
ZRANK leaderboard
须要精准设定过时时间的应用
好比你能够把上面说到的sorted set的score值设置成过时时间的时间戳,那么就能够简单地经过过时时间排序,定时清除过时数据了,不只是清除Redis中的过时数据,你彻底能够把Redis里这个过时时间当成是对数据库中数据的索引,用Redis来找出哪些数据须要过时删除,而后再精准地从数据库中删除相应的记录。
范围查找
来自Redis在Google Group上的一个问题,有一位同窗发贴求助,说要解决以下的一个问题:他有一个IP范围对应地址的列表,如今须要给出一个IP的状况下,迅速的查找到这个IP在哪一个范围,也就是要判断此IP的全部地。这个问题引来了Redis做者Salvatore Sanfilippo(@antirez)的回答。解答以下:
例若有下面两个范围,10-20和30-40
redis 127.0.0.1:6379> zadd ranges 10 A_start
redis 127.0.0.1:6379> zadd ranges 20 A_end
redis 127.0.0.1:6379> zadd ranges 30 B_start
redis 127.0.0.1:6379> zadd ranges 40 B_end
这样数据在插入sorted set后,至关因而将这些起始位置按顺序排列好了。
如今我须要查找15这个值在哪个范围中,只须要进行以下的zrangbyscore查找:
redis 127.0.0.1:6379> zrangebyscore ranges (15 +inf LIMIT 0 1
这个命令的意思是在Sorted Sets中查找大于15的第一个值。(+inf在Redis中表示正无穷大,15前面的括号表示>15而非>=15)
查找的结果是A_end,因为全部值是按顺序排列的,因此能够断定15是在A_start到A_end区间上,也就是说15是在A这个范围里。至此大功告成。
固然,若是你查找到的是一个start,好比我们用25,执行下面的命令:
redis 127.0.0.1:6379> zrangebyscore ranges (25 +inf LIMIT 0 1
返回结果代表其下一个节点是一个start节点,也就是说25这个值不处在任何start和end之间,不属于任何范围。
固然,这个例子仅适用于相似上面的IP范围查找的案例,由于这些值范围之间没有重合。若是是有重合的状况,这个问题自己也就变成了一个一对多的问题。
Pub/Sub
Pub/Sub 从字面上理解就是发布(Publish)与订阅(Subscribe),在Redis中,你能够设定对某一个key值进行消息发布及消息订阅,当一个key值上进行了消息发布后,全部订阅它的客户端都会收到相应的消息。这一功能最明显的用法就是用做实时消息系统,好比普通的即时聊天,群聊等功能。
使用场景
Pub/Sub构建实时消息系统
Redis的Pub/Sub系统能够构建实时的消息系统
好比不少用Pub/Sub构建的实时聊天系统的例子。
参考:
深刻浅出redis底层数据结构系列
https://www.cnblogs.com/jaycekon/p/6227442.html(上)
https://www.cnblogs.com/jaycekon/p/6277653.html(下)
http://www.redis.net.cn/tutorial/3501.html http://www.cnblogs.com/markhe/p/5689356.html http://www.cnblogs.com/ggjucheng/p/3349102.html https://blog.csdn.net/Richard_Jason/article/details/53130369