Redis (三) 命令示例
1.String 字符串:
存储类型:可以用来存储字符串、整数、浮点数。
//设置多个值(批量操作,原子性) mset key1 value1 key2 value2 //设置值,如果 key 存在,则不成功 setnx key1 value1 //基于setnx 可实现分布式锁。用 del key 释放锁。但如果释放锁的操作失败了,导致其他节点永远获取不到锁,怎么办?加过期时间。单独用 expire 加过期,也失败了,无法保证原子性,怎么办?多参数 set key value [expiration EX seconds|PX milliseconds][NX|XX] //使用参数的方式 set lock1 1 EX 10 NX //(整数)值原子递增 incr key1 incrby qingshan 100 //(整数)值递减 decr qingshan decrby qingshan 100 //浮点数增量 set f 2.6 incrbyfloat f 7.3 //获取多个值 mget key1 key2 //获取值长度 strlen key1 //字符串追加内容 append key1 good //获取指定范围的字符 getrange key 0 8 //位计算 set k1 a setbit k1 6 1 setbit k1 7 0 get k1 //key 分层的方式 student 表 有ID 字段 sno字段 sname字段 company字段 mset student:1:sno 8888 student:1:sname 沐风 student:1:company 腾讯 //获取值的时候一次获取多个值: mget student:1:sno 9999 student:1:sname java student:1:company alibaba
应用场景:
- 缓存String 类型,例如:热点数据缓存,对象缓存,全页缓存。可以提升热点数据的访问速度。
- 数据共享:因为 Redis 是分布式的独立服务,可以在多个应用之间共享.例如:分布式 Session
- 分布式锁:setnx 方法,只有不存在时才能添加成功,返回 true。
- 全局 ID:INCRBY,利用原子性.例如:文章的阅读量,微博点赞数,允许一定的延迟,先写入 Redis 再定时同步到数据库。(限流)以访问者的 IP 和其他信息作为 key,访问一次增加一次计数,超过次数则返回 false。
缺点:key 太长,占用的空间太多。
2.Hash 哈希
存储类型:包含键值对的无序散列表。value 只能是字符串,不能嵌套其他类型。
同样是存储字符串,Hash 与 String 的主要区别?
- 把所有相关的值聚集到一个 key 中,节省内存空间
- 只使用一个 key,减少 key 冲突
- 当需要批量获取值的时候,只需要使用一个命令,减少内存/IO/CPU 的消耗
Hash 不适合的场景:
- Field 不能单独设置过期时间
- 没有 bit 操作
- 需要考虑数据量分布的问题(value 值非常大的时候,无法分布到多个节点)
//设置值 hset wuzz name wuzz //设置值 hset wuzz age 18 //设置多个值 hmset wuzz sex m height 180 //获取值 hget wuzz name //批量获取 hmget wuzz name age sex height //获取keys hkeys wuzz //获取vals hvals wuzz //获取所有 hgetall wuzz //是否存在 hget exists wuzz //删除 hdel wuzz age hgetall wuzz //原子递增 hincrby wuzz age 1
应用场景:
hash 类型十分适合存储对象类数据,相对于在 string 中介绍的把对象转化为 json 字符串存储,hash 的结构可以任意添加或删除‘字段名’,更加高效灵活。String 可以做的事情,Hash 基本都可以做(位运算除外)。
3.List 列表
存储类型:存储有序的字符串(从左到右),元素可以重复。可以充当队列和栈的角色。
//设置值 此时队列是 a lpush queue a //设置值 此时队列是 c b a lpush queue b c //设置值 此时队列是 c b a d e rpush queue d e //从左边取出值 则是 c 采用blpop会没有任何元素可以弹出的时候,连接会被阻塞 lpop queue //取出所有值 lrange queue 0 -1 //获取指定位置的值 lindex queue 0 //取出右边第一个 rpop queue
应用场景:
因为 List 是有序的,可以用来做用户时间线(排序相关)
消息队列:List 提供了两个阻塞的弹出操作:BLPOP/BRPOP,可以设置超时时间。BLPOP:BLPOP key1 timeout 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。BRPOP:BRPOP key1 timeout 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。队列:先进先出:rpush blpop,左头右尾,右边进入队列,左边出队列。栈:先进后出:rpush brpop
4.Set 集合
存储类型:String 类型的无序集合,最大存储数量 2^32-1(40 亿左右)。
//添加一个或者多个元素 sadd myset a b c d e f g //获取所有元素 smembers myset //统计元素个数 scard myset //随机获取一个元素 srandmember key //随机弹出一个元素 spop myset //移除一个或者多个元素 srem myset d e f //查看元素是否存在 sismember myset a //获取差集 sdiff set1 set2 //获取交集( intersection ) sinter set1 set2 //获取并集 sunion set1 set2
应用场景:
- 抽奖:随机获取元素。
- 点赞 、签到、打卡:比如有条微博的 ID 是 t1001,用户 ID 是 u3001。用 like:t1001 来维护 t1001 这条微博的所有点赞用户。点赞了这条微博:sadd like:t1001 u3001取消点赞:srem like:t1001 u3001是否点赞:sismember like:t1001 u3001点赞的所有用户:smembers like:t1001点赞数:scard like:t1001
- 商品标签:维护商品所有的标签。某个商品有的一些标签都可以维护到set里。
5.ZSet 有序集合:
sorted set,有序的 set,每个元素有个 score。score 相同时,按照 key 的 ASCII 码排序。数据结构对比:
//添加元素 zadd myzset 10 java 20 php 30 ruby 40 cpp 50 python //获取全部元素 zrange myzset 0 -1 withscores zrevrange myzset 0 -1 withscores //根据分值区间获取元素 zrangebyscore myzset 20 30 //移除元素 也可以根据 score rank 删除 zrem myzset php cpp //统计元素个数 zcard myzset //分值递增 zincrby myzset 5 python //根据分值统计个数 zcount myzset 20 60 //获取元素 rank zrank myzset java //获取元素 score zsocre myzset java //也有倒序的 rev 操作(reverse)
应用场景:
排行榜:id 为 6001 的新闻点击数加 1:zincrby hotNews:20190926 1 n6001.获取今天点击最多的 15 条:zrevrange hotNews:20190926 0 15 withscores.
6.其他数据类型介绍:
在 2.8.9 版本添加了 HyperLogLog 结构。Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,例如统计一个集合里面不同元数的个数,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。
这里还需要说明的是另外一种数据类型 geospatial indexes 。这个东东是可以用来做地理位置信息存储及简单计算的,比如要获取某个经纬度的点方圆多少公里内的点的经纬度,两个点之间的距离等等。
//设置某个点的经纬度 geoadd location 120.1 29.2 hangzhou //获取 geopos location hangzhou
对于其他的一些操作,就Redis的java客户端来说,Jedis也已经提供了这个地理空间功能的基本操作Api