string 一个key对应一个value(和Memcached一样),字符串是一种最基本的Redis值类型。Redis字符串是二进制安全的,这意味着一个Redis字符串能包含任意类型的数据,例如: 一张JPEG格式的图片或者一个序列化的Ruby对象,一个字符串类型的值最多能存储512M字节的内容。
基础命令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 # 常见增删改 1.get set 2.append k1 12345 3.strlen k1 获取长度 4.incr k2 (set k2 2)增加整数的值比如浏览量加放在redis 5.decr k2 减 6.incrby k2 3 加3 7.decrby k2 2 减2(封装原子操作,一个线程加,一个减) 8.getrange # 获取区间范围的值类似与between and getrange k1 0 -1 # 获取0到-1的值 getrange k1 0 3 # 和切片一样 9.setrange修改开始位置的值 setrange k1 0 xxx 把前三个数设置为xxx get k1 10.setex(set with expire)键秒值/setnx(set if not exists) setex k1 10 v4设置10秒过期 setnx k1 v100返回0表示已存在无法设置 11.mset/mget/msetnx d多个设置,获取 mset k1 v1 k2 v2 k3 v3 msetnx k1 v1 k5 v5 只要有一个存在就翻车 12.getset getset k1 v100(获取原来的值,赋予新的值)
应用场景
作为邮件开关,点击开关
计数器,粉丝数、购买人数、浏览人数、限流(incr,decr)
使用setbit/getbit实现bloom过滤器
这里需要注意的是,redis本身是单线程的,所以做计数器不用考虑并发带来的影响,且redis内存存储并支持集群、持久化的特性,使得redis高效快速,适合做高并发系统的计数器。bloom是解决缓存穿透的有效方法(请求进来先用bloom判断是否存在,存在再去那数据不存在直接返回),也是过滤一些特定大数据的解决方案(比如几亿的用户,需要看进来的用户是否是新用户
redis的list底层是双向链表的结构,其底层实现有三种linkdlist、ziplist和quicklist。
redis 3.2之前 默认使用linklist和ziplist linklist作为基础的朴素双向链表。 ziplist作为基本存储的压缩双向链表,ziplist所有信息保存在连续的内存中,每次修改都需要realloc或者memmove,所以效率比较低,是为了节省内存设计的。 ziplist要求单个节点小于64bytes,总数量小于512个,当数据量超出标准就会使用linkedlist,最大为2**32-1个值
redis 3.2 之后 使用quicklist作为默认底层
基础命令 1 2 3 4 5 6 7 8 9 10 11 lpush/rpush k v lrange k start end lpushx/rpushx k v(当k不存在不会创建) lpop/rpop k lrem k count v 移除指定个数的值为v的元素,count=0移除所有 ltrim k start end 截取并保留范围值 lindex k idx 索引 llen k linsert k after|before v value 在固定的某个元素前或者后插入元素 rpoplpush k v lset k idx v
应用场景
消息队列(celery)安全消息队列复制一份进行操作避免消费者异常
排行榜(每隔一段时间更新一次)
最新列表(点赞列表、评论列表)(固定条数左进右出)
ziplist源码分析 ziplist是一种特殊编码的节省内存空间的双链表,能以O(1)的时间复杂度在两端push和pop数据,具有如下结构:
zlbytes是一个unsigned integer,保存ziplist占用的总内存空间,在重新分配内存时,借助这个字段可以不用遍历整个ziplist;
zltail是指向最后一个entry的偏移量,这样对于尾部的操作不用去遍历所有entry;
zllen固定两个字节长度,表示entry的数量,最大能表示2^16-2个entry,如果超过了,则其值为2^16-1,需要遍历entry才能知道具体的数量;
zlend固定一个字节,值固定为255,表示ziplist的结尾。1 2 3 4 5 6 7 8 9 10 11 # ziplist.c /* Create a new empty ziplist. */ unsigned char *ziplistNew(void) { unsigned int bytes = ZIPLIST_HEADER_SIZE+1; unsigned char *zl = zmalloc(bytes); ZIPLIST_BYTES(zl) = intrev32ifbe(bytes); ZIPLIST_TAIL_OFFSET(zl) = intrev32ifbe(ZIPLIST_HEADER_SIZE); ZIPLIST_LENGTH(zl) = 0; zl[bytes-1] = ZIP_END; return zl; }
hash KV模式不变,但v是一个键值对,理论最大为2^32-1个键值对
基础命令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1.hset/hget/hmset/hmget/hgetall/hdel hset user id 11 hget user id hmset cutomer name z3 id 2 age 26 hmget customer id name age hgetall customer hdel user name 2.hlen user 3.hexists key hexists customer id 4.hkeys/hvals hkeys customer 获取所有的键/值 5.hincrby/hincrbyfloat hincrby customer age 1 hset customer score 91.5 hincrby customer score 1.5 6.hsetnx
应用场景
用户信息存储 ,如果用string存储用户信息打包,内容修改时需要取出全部信息,使用hash只需要取出该字段即可。
购物车数据 ,未登录用cookie存储购物车数据,登录使用redis的hash存储数据。
内部源码 set 基础命令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1.sadd/smembers/sismember sadd set01 1 1 2 2 3 3会把重复的数去掉并构建set smembers set01 查看set01的元素 sismember set01 x 是成员返回1不是0 2.scard scard set01 获取set01元素个数 3.srem key vlaue 删除集合中的元素 srem set01 3 4.srandmember set02 3从集合中随机取出3个 (就像什么抽红包,从100个里面随机抽10个) 5.spop key 随机出栈 spop set01 6.smove key1 key2 val在key1里的某个值 赋给key2 smove set02 set01 7 smembers set01 7.数学集合类 差集:sdiff sdiff set01 set02 在第一个里面不在第二个里面的 sdiff set02 set01 交集:sinter sinter set01 set02相交部分 并集:sunion set01 set02
应用场景
共同好友、共同关注、相似关注、共同喜好
可以将一个用户的所有关注存在一个集合,粉丝存在一个集合
去重
内部源码 zset和set一样也是string类型元素的集合,且不允许重复的成员不同的是(在set的基础上加)每个元素都会关联一个double类型的分数,redis正是通过分数来为集合中的成员来进行大小排序,zset的成员是唯一的,但分数score可以重复。
zset(sorted set) 基础命令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1.zadd/zrange zadd zset01 60 v1 70 v2 80 v3 90 v4 100 v5 zrange zset01 0 -1 zadd 60 v9 zrange zset01 0 -1 withscores 2.zrangebyscore key zrangebyscore zset 60 90 60到90分的 3.zrangebyscore zset01 (60 (90 大于60小于90不包含 4. zrangebyscore key 60 90 limit 2 2 从第二个开始截取两个 5.zrem zseto1 v5 删除v5 6.zcard 统计个数 zcard zset01 7.zcount + key + score区间 zcount zset01 60 80统计60到80的数量 8.zrank zset04 v4获取下标的值(索引值) 9.zscore zset01 v4获取v4的得分 10.zrevrank key values 逆序获得下标 11.zrevrange zset01 0 -1逆序遍历 12.zrevrangebyscore key
应用场景
内部源码