之前的文章中说了Redis的常见应用场景和特性,在特性章节中也大致说了数据结构契合场景。因为我想在更深入、更全面的学习Redis之前,了解场景和特性,才能在学习时更加全面且理解更透彻:
- redis的什么特性支持这些应用场景?
- 为什么这些场景下使用redis会带来好处?
数据类型
Redis数据结构大体上是一种key-value形式,根据value的不同数据类型,将其分为以下几种。其中Bitmap并不是一种新的数据类型,它其实是将String类型的每一位限制成0或1实现,详见Bitmaps文档。
数据类型 | 描述 | 操作命令 | 应用场景 |
---|---|---|---|
String | value是String | set、get、incr、incrby、setnx、 setex、 | k-v分布式缓存、分布式锁、 过期值、分布式session |
List | value是List列表 | lpush、lpop、lrange、 rpush、rpop、 lindex、llen、lrem、 brpop | 任务队列、消息队列、最新信息 |
Hash | value是Hash映射表 | hset、hget、hdel、 hexists、hgetall、 hincby、hkeys、hlen、 hmset | 对象缓存 |
Set | value是无序的Set集合 | sadd、smembers、sismembers、 scard、sinter、sdiff、sunion、 spop、srem | 文章tag |
Sorted Set | value是有序的Set集合 | zadd、zcard、zcount、zincrby、 zrange、zrangebylex、 zrangebyscore、zrank、 zrem、zrevrange | 排行榜 |
Bitmap | value是0/1 | setbit、getbit、bitcount、 bittop | 用户状态、用户在线时间 |
除了以上几种,Redis还支持hyperloglogs和geospatial类型,由于不是很常用,这里不做介绍。具体可以参考方Introduction to Redis文档。
每种数据类型除了各自相应的读写删命令,这些数据类型还有共性命令。为何共性,因为这些共性命令是作用在key上,上面也说到了,redis的数据结构大体上是key-value结构。
exists命令
1.语法:
exists key [key...]
2.用途:
用于检测指定key是否存在
del命令
1.语法
del key [key...]
2.用途
删除指定key
expire和pexpire命令
1.语法
expire key seconds
pexpire key millseconds
2.用途
expire用于设置key的过期时间,单位秒。pexpire也是用于设置key的过期时间,单位毫秒
keys命令
1.语法
keys pattern
2.用途
用于查找指定模式的key,支持glob-style pattern。详情参考KEYS pattern文档
简单的命令操作
Redis提供了操作的命令行redis-cli,在下载的redis包中的bin目录下。在启动了redis-server的前提下,直接运行redis-cli即可进入redis命令行:
$ redis-cli
127.0.0.1:6379>
127.0.0.1:6379>
下面通过redis-cli命令行来认识下redis中的常用数据类型
1.String类型
// set命令设置k-v
127.0.0.1:6379> set key value
OK
// get命令获取指定key的值
127.0.0.1:6379> get key
"value"
//setnx如果key存在则不设置,否则设置
127.0.0.1:6379> setnx key value
(integer) 0
127.0.0.1:6379> setnx key1 value1
(integer) 1
//setex设置k-v和过期时间
127.0.0.1:6379> setex key2 60 value2
OK
127.0.0.1:6379> ttl key2
(integer) 56
127.0.0.1:6379> ttl key2
(integer) 54
//incr指定key的值自增长
127.0.0.1:6379> set key3 5
OK
127.0.0.1:6379> incr key3
(integer) 6
//incrby指定key的值增长幅度
127.0.0.1:6379> incrby key3 100
(integer) 106
2.List类型
//lpush从左边推入value至list中
127.0.0.1:6379> lpush list value1 value2 value3
(integer) 3
//lrange按范围获取list中的value,
//第一个表示起始索引,第二个表示结束索引。-1表示所用
127.0.0.1:6379> lrange list 0 -1
1) "value3"
2) "value2"
3) "value1"
//rpop表示从右边弹出一个value
127.0.0.1:6379> rpop list
"value1"
//lindex获取指定位置的vlaue
127.0.0.1:6379> lindex list 0
"value3"
//llen获取list的大小
127.0.0.1:6379> llen list2
(integer) 8
//brpop阻塞从右边弹出元素。参数5指定阻塞超时时间,0表示永久
127.0.0.1:6379> brpop list2 5
(nil)
(5.04s)
3.Hash类型
//hset设置映射表的k-v
127.0.0.1:6379> hset map name lxy
(integer) 1
//hmset同时设置多个映射表的k-v
127.0.0.1:6379> hmset map age 11 sex male
OK
//hgetall获取映射表的所有k-v
127.0.0.1:6379> hgetall map
1) "name"
2) "lxy"
3) "age"
4) "11"
5) "sex"
6) "male"
//hget获取映射表的指定k的v
127.0.0.1:6379> hget map age
"11"
//hlen获取映射表的大小
127.0.0.1:6379> hlen map
(integer) 3
//hexists探测映射表的指定k是否存在
127.0.0.1:6379> hexists map address
(integer) 0
//hdel删除映射表指定k-v
127.0.0.1:6379> hdel map name
(integer) 1
//hincrby幅度增长映射表指定k的v
127.0.0.1:6379> hincrby map age 20
(integer) 31
4.Set类型
//sadd向set中添加v,无重复
127.0.0.1:6379> sadd set v1 v2 v3 v4 v4 v5
(integer) 5
//scard探测set元素个数
127.0.0.1:6379> scard set
(integer) 5
//smembers获取set所用元素
127.0.0.1:6379> smembers set
1) "v4"
2) "v1"
3) "v2"
4) "v3"
5) "v5"
//探测指定set是否存在某个元素
127.0.0.1:6379> sismember set v8
(integer) 0
//sinter计算多个set的交集
127.0.0.1:6379> sinter set set1
1) "v3"
2) "v5"
//sunion计算多个set的并集
127.0.0.1:6379> sunion set set1
1) "v6"
2) "v2"
3) "v3"
4) "v9"
5) "v4"
6) "v1"
7) "v7"
8) "v5"
9) "v8"
//计算第一个set与其他set的差集
127.0.0.1:6379> sdiff set set1
1) "v2"
2) "v4"
3) "v1"
5.Sorted Set类型
//zadd想sorted set中添加元素
127.0.0.1:6379> zadd ss 0 v0 1 v1 3 v4 4 v3 5 v5
(integer) 5
//zcard计算sorted set的元素个数
127.0.0.1:6379> zcard ss
(integer) 5
//zcount统计指定score范围的元素个数
127.0.0.1:6379> zcount ss 0 1
(integer) 2
//zrange获取指定索引范围的元素
127.0.0.1:6379> zrange ss 0 3
1) "v0"
2) "v1"
3) "v4"
4) "v3"
5.Bitmap类型
//setbit设置指定bit位v
127.0.0.1:6379> setbit user 1 0
(integer) 0
127.0.0.1:6379> setbit user 2 1
(integer) 0
127.0.0.1:6379> setbit user 3 1
(integer) 0
127.0.0.1:6379> setbit user 4 0
(integer) 0
//getbit获取指定bit位的v
127.0.0.1:6379> getbit user 2
(integer) 1
//统计指定key的bit位为1的个数
127.0.0.1:6379> bitcount user
(integer) 2
6.通用键
//expire设置k的过期时间
127.0.0.1:6379> expire user 5
(integer) 1
127.0.0.1:6379> ttl user
(integer) 1
127.0.0.1:6379> exists user
(integer) 0
//keys探测redis中存在哪些k
127.0.0.1:6379> keys *
1) "sk"
2) "name"
3) "ss"
4) "map"
5) "set"
6) "m"
7) "set1"
8) "list"
9) "k"
//del删除指定的k
127.0.0.1:6379> del name sk map
(integer) 3
以上是以命令的方式学习理解redis的数据结构,但是在日常开发中基本上是使用某种语言的redis客户端与redis交互操作。
redis支持丰富的各种语言的客户端,单独对java而言就存在很多种选择,jedis是一个非常不错和普遍被使用的java版本redis client。开源地址xetorthio/jedis,对于jedis的使用api,可以参考其开源项目中的丰富测试类jedis/src/test/java/redis/clients/jedis/tests/commands/