(二)Redis API的使用和理解

二、Redis API的使用和理解

  • 通用命令
  • 字符串类型
  • 哈希类型
  • 列表类型
  • 集合类型
  • 有序集合类型

1.通用命令

  • 通用命令:
    • keys:列出redis中所有的键
      • 例如:keys *
      • keys [pattern] pattern是通配符或者说是正则表达式的形式
      • 注意:keys一般不在生产环境中使用(意义不大,O(n))
      • 一般用在热备从节点、scan中
    • dbsize:算出redis数据库中键的总数
      • dbsize的时间复杂度是O(1),有个专门的计数器
    • exists key 判断键是否存在
    • del key [key...] 删除键-值对
    • expire key seconds 设置key的存活时间,key在seconds秒后过期,过期的时候内部执行del命令删除键-值对
      • 此外还有:ttl key:查看key的剩余的过期时间
      • persist key:去掉key的过期时间,即不进行计时删除的操作了
    • type key 得到键对应的值的数据类型
    • 综上,除keys命令时间复杂度是O(n)外,其余的命令都是O(1)的复杂度
  • 数据结构和内部编码
    • key
      • string
        • raw
        • int
        • embstr
      • hash
        • hashtable
        • ziplist
      • list
        • linkedlist
        • ziplist
      • set
        • hashtable
        • intset
      • zset(sorted-set)
        • skiplist
        • ziplist
  • 单线程架构
    • 单线程为什么这么快?
      • 1.纯内存(内存的响应时间小于100ns)
      • 2.非阻塞IO
      • 3.避免线程切换和竞态消耗
    • 一次只运行一条命令
    • 拒绝长(慢)命令
      • 比如:keys、flushall、flushdb、slow lua script、multi/exec、operate big value(Collection)
    • 其实不是单线程
      • 处理下面两种操作时有独立的线程
      • fsync file descriptor
      • close file descriptor

2.字符串类型

结构和命令

key			value
hello		world(真的字符串)
counter		1(转换成整数类型)
bits		1010101010 (最高512MB)
场景
  • 缓存
  • 计数器
  • 分布式锁
  • ...
命令
  • get key
  • set key value
  • del key
  • incr key
  • decr key
  • incrby key k
  • decrby key k
  • set key value
  • setnx key value 只有key不存在,才设置
  • set key value xx 只有key存在,才设置,xx是命令的一部分
  • mget key1 key2 key3... 批量获取key的值,原子操作,批量操作效率高,减少网络IO次数 O(n)
  • mset key1 value1 key2 value2...批量设置key-value

快速实战

  • 实现如下功能:记录网站每个用户个人主页的访问量?incr userid:pageview(单线程,无竞争)
  • 缓存视频的基本信息(数据源在MySql中):
    • 伪代码:

        public VideoInfo get(long id){
        	String redisKey = redisPrefix + id;
        	VideoInfo videoInfo  = redis.get(redisKey);
        	if (videoInfo == null){
        		videoInfo = mysql.get(id);
        		if (videoInfo != null){
        			//序列化
        			redis.set(redisKey, serialize(videoInfo));
        		}
        	}
        	return videoInfo;
        }
      

查漏补缺

  • getset key newvalue 设置为新的值,并返回旧的值
  • append key value 将value追加到旧的value
  • strlen key 返回字符串(value)的长度(使用中文的时候要注意)
  • incrbyfloat key 3.5 浮点数自增
  • getrange key start end 获取字符串指定下标所有的值
  • setrange key index value 设置指定下标所有对应的值

3.哈希类型

特点

  • Mapmap
  • Small Redis
  • field不能相同,value可以相同

结构例如:

key field value
email john@gmail.com
user:1:info name John
password 123456
id 1

重要API

  • hget key field 获取hash key对应的field的value
  • hset key field value 设置hash key对应的field的value
  • hdel key field 删除hash key中的某个field
  • hexists key field 判断一个field是否存在
  • hlen key 获取hash key field的数量
  • hmget key field1 field2...fieldN 批量获取hash key的一批field对应的值
  • hmset key field1 value1 field2 value2... 批量设置hash key的一批field value
  • hgetall key 返回hash key对应的所有field和value(小心使用,防止数据量过大)
  • hvals key 返回hash key对应所有field的value
  • hkeys key 返回hash key对应所 有field

实战

1.记录网站每个用户个人主页的访问量?
hincrby user:1:info pageview count

2.缓存视频的基本信息:

    	public VideoInfo get(long id){
   			String redisKey = redisPrefix + id;
	    	Map<String,String> hashMap = redis.hgetAll(redisKey);
	    	VideoInfo videoInfo = transferMapToVideo(hashMap);
			if (videoInfo == null){
				videoInfo = mysql.get(id);
				if (videoInfo != null){
					redis.hmset(redisKey,transferVideoToMap(videoInfo));
				}
			}
			return videoInfo;
    	}

hash vs String





查漏补缺

  • hsetnx key field value 设置hash key对应field的value(如果field已经存在,则操作失败)
  • hincrby key field intCounter hash key对应field的value自增intCounter
  • hincrbyfloat key field floatCounter hash key对应field的value自增浮点数floatCounter

4.列表

列表结构



特点

  • 有序
  • 元素可以重复
  • 左右两边都可以插入和弹出

重要API

  • rpush key value1 value2... 从列表右端依次插入值
  • lpush key value1 value2... 从列表左端依次插入值
insert
  • insert key before|after value newvalue 在list指定的值 前|后 插入newvalue 时间复杂度O(n)
删除
  • lpop key 从列表左端弹出一个元素
  • rpop key 从列表右端弹出一个元素
  • lrem key count value 根据count值,从列表中删除所有value相等的项
    • count>0:从左到右,删除最多count个value相等的项
    • count<0:从右到左,删除最多abs(count)个value相等的项
    • count=0:删除所有value相等的项
  • ltrim key start end 按照索引范围修建列表(保留下标start到end之间的元素)
  • lrange key start end(包含end) 获取列表指定范围内的的元素


  • lindex key index 获取列表指定索引的元素
  • llen key 获取列表长度
  • lset key index newvalue 设置列表指定索引值为newvalue

实战

微博TimeLine

查漏补缺

  • blpop key timeout lpop的阻塞版本,timeout是阻塞超时时间,timeout=0为永远不阻塞
  • brpop key timeout

Tips

LPUSH + LPOP = STACK
LPUSH + RPOP = QUEUE
LPUSH + LTRIM = Capped Collection(固定大小列表)
LPUSH + BRPOP = Message Queue

5.Set

集合结构

特点

  • 无序
  • 没有重复元素
  • 支持集合间操作

集合内API

  • sadd key element 向集合中添加元素
  • srem key element 将集合key中的element删除
  • scard key 计算集合大小
  • sismember key element 判断element是否在集合key中
  • srandmember key count 从集合中随机挑count个元素
  • spop key 从集合中随机弹出一个元素(会破会集合数据,即弹出就没了)
  • smemebers key 取出集合key中所有的元素,返回结果是无序的(小心使用,数据量可能很大)

集合内实战

  1. 给用户添加标签:
    1. sadd user:1:tags tag1 tag2 tag3
    2. sadd user:2:tags tag2 tag3 tag5
  2. 给标签添加用户
    1. sadd tag1:users user:1 user:3
    2. sadd tag2:users user2: user:4
  3. 微博抽奖系统:将用户放在一个集合中,然后通过spop或者srandmember来抽取用户
  4. 微博点赞、点踩(把用户id放在某条微博的赞、踩集合中)

集合间API

  • sdiff key1 key2 差集
  • sinter key1 key2 交集
  • sunion key1 key2 并集

集合间实战

比如求用户的共同关注

Tips

SADD = Tagging
SPOP、SRANDMEMBER = Random item
SADD + SINTER = Social Graph

有序集合

结构



集合里每个元素是有序的,根据score排序

集合和有序集合对比

重要API

  • zadd key score element 注意score可以重复,element不可以重复O(logN)
  • zrem key element 删除元素 O(1)
  • zscore key element 返回元素的分数
  • zincryby key increScore element 增加或减少元素的分数
  • zcard key 返回元素的个数 O(1)
  • zrank key element 获取某个元素的排名(从0开始数)
  • zrange key start end [withscores] [带分数]返回指定范围的升序元素 O((logN) + m)
  • zrangebyscore key minScore maxScore [withscores] [带分数]返回指定分数范围内的升序元素 时间复杂度同上
  • zcount key minScore maxScore 返回个数
  • zremrangebyrank key start end 删除指定排名内的升序元素

实战

排行榜:可以使用timeStamp、saleCount或者followCount作为score

查缺补漏

  • zrevrank 降序
  • zrevrange 降序
  • zrevrangebyscore 降序
  • zinterstore
  • zunionstore
posted @ 2020-05-23 22:18  scnb  阅读(149)  评论(0)    收藏  举报