简介
REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。
Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。
Redis-key
- 查看所有的key
keys * - 添加一个key
set key value - 判断键是否存在
exists key - 设置键过期时间
expire key time(秒) - 移除当前的key
move key - 查看当前key的剩余时间
ttl key - 查看键的类型
type key - ......
String(字符串)
-
设置值
set 键 值 -
获取键值
get 键 -
获取所有的键
keys * -
判断某一个key是否存在
exists 键 -
追加字符串
append 键 "追加值"如果当前key不存在,就相当于set key -
键值自增1
incr 键自减1decr 键(应用场景,统计浏览量)- 按指定步长(设置增量)自增
incrby 键 步长自减decrby 键 步长
- 按指定步长(设置增量)自增
-
字符串范围range
- 截取字符串
GETRANGE 键 下标1 下标2 - 截取全部
GETRANGE 键 0 -1
- 截取字符串
-
替换
- 替换指定位置开始的字符串
SETRANGE 键 下标 新的值
- 替换指定位置开始的字符串
-
过期时间
- 设置过期时间
setex(set with expire) - 不存在设置(在分布式锁中常常使用)
setnx(set if not exist)- eg: 设置key1的值为sayhi 30秒后过期
setex key1 30 "sayhi" - eg:如果mykey不存在 创建mykey
setnx mykey "redis" - eg:如果mykey存在 创建失败
setnx mykey "MongoDB"
- eg: 设置key1的值为sayhi 30秒后过期
- 设置过期时间
-
批量处理
-
mset- 同时设置多组值
mset k1 v1 k2 v2 k3 v3
- 同时设置多组值
-
mget- 同时获取多组值
mget k1 k2 k3
- 同时获取多组值
-
msetnxmsetnx是一个原子性的操作,要么一起成功,要么一起失败
-
-
对象
set user:1 {name:zhangsan,age:18}设置一个user:1对象 值为json字符来保存一个对象.
-
先get再set
getset- 如果不存在值 则返回nil
getset db redis - 如果存在值,获取原来的值,并设置新的值
getset db mongodb
- 如果不存在值 则返回nil
String 类似的使用场景: value不仅仅是字符串,还可以是数字!
- 计数器
- 统计多单位的数量
- 粉丝数
- 点赞数
- .......
List
在Redis中,可以使用list做栈,队列,阻塞队列!
-
添加
- 将一个值或多个值插入列表的头部(左)
LOUSH list键 名 - 将一个值或多个值插入列表的尾部(右)
ROUSH list键 名 - 获取list中的值
LRANGE list键 下标1,下标2 - 通过区间获取具体的值
LRANGE list 0 1
- 将一个值或多个值插入列表的头部(左)
-
移除
- 移除列表的第一个元素
Lpop list - 移除列表的最后一个元素
Rpop list
- 移除列表的第一个元素
-
返回列表长度
Llen -
移除指定的值
- 移除列表中指定个数的value,精确匹配
lren list键 1 one(移除一个one)
- 移除列表中指定个数的value,精确匹配
-
list截取
- 通过下标截取指定的长度,这个list已经被修改了 截断了只剩下截取的元素
ltrim mylist键 1 2
- 通过下标截取指定的长度,这个list已经被修改了 截断了只剩下截取的元素
-
综合
- 移除列表的最后一个元素 并移动到新的列表中
rpoplpush
- 移除列表的最后一个元素 并移动到新的列表中
-
替换指定下标的值(更新)
- 判断列表是否存在
exists 列表 - 如果不存在的列表更新会报错
(error)ERR no such key - 如果存在更新当前下标的值
lset 键 小标 值
- 判断列表是否存在
-
插入
- 在元素后面添加指定value
Linsert 键 before 定位值 "新value" - 在元素前面添加指定value
linsert 键 after 定位值 "新值"
- 在元素后面添加指定value
小结
- list实际是一个链表,before node after left right 都可以插入值
- 如果key不存在,创建新的链表
- 如果key存在,新增内容
- 如果移除了所有值,空链表,也代表不存在!
- 在两边插入或者改动值 效率最高! 中间元素,相对而言效率低一些
@Resource
private RedisTemplate<Object,Object> redisTemplate;
@Test
void testContextList(){
ListOperations listOperations = redisTemplate.opsForList();
listOperations.leftPush("list","ddd");
listOperations.leftPush("list","hhh");
listOperations.leftPush("list","ddd");
Object list = listOperations.rightPop("list");
System.out.println(list);
listOperations.range("list",0,2);
}
set
set中的值是不能重读的!
Redis Set 对外提供的功能与 List 类似,是一个列表的功能,特殊之处在于 Set 是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,Set 是一个很好的选择,并且 Set 提供了判断某个成员是否在一个 Set 集合内的重要接口,这个也是 List 所不能提供的。
-
添加元素
- 给集合添加一个元素
sadd 键 值 - 查看指定set的所有值
smembers 键 - 判断某一个值是不是在set集合中
sismember 键 值
- 给集合添加一个元素
-
获取集合中的内容元素个数
scard 键 -
移除元素
- 移除set集合中的指定元素
srem 键 值
- 移除set集合中的指定元素
set: 无序不重复集合! 随机
-
随机抽元素
- 随机抽出一个元素
srandmember 键 - 随机抽出指定个数元素
srandmember 键 数
- 随机抽出一个元素
-
删除set元素
- 随机删除一个set集合中的元素
spop 键
- 随机删除一个set集合中的元素
-
将一个指定的值.移动到另外一个set集合
smove 原集合 新集合 移动的值共同关注(并集)
数字集合类:
- 差集
sdiff 键1 键2- 交集
sinter 键1 键2共同好友实现方式- 并集
sunion 键1 键2
@Resource
private RedisTemplate<Object,Object> redisTemplate;
@Test
void testObsSet(){
SetOperations setOperations = redisTemplate.opsForSet();
setOperations.add("name","admin");
setOperations.add("name","lily");
setOperations.add("name","john");
setOperations.add("age","18");
setOperations.add("type","1");
Set name = setOperations.members("name");
name.forEach(e->{
System.out.println(e);
});
}
Hash(哈希)
Map集合 本质和String没有太大区别 还是一个简单的key-value
一般我们存储一个键,很自然的就会使用 get/set 去存储,实际上这并不是很好的做法。Redis 存储一个 key 会有一个最小内存,不管你存的这个键多小,都不会低于这个内存,因此合理的使用 Hash 可以帮我们节省很多内存。
Hash Set 就在哈希表 Key 中的域(Field)的值设为 value。如果 Key 不存在,一个新的哈希表被创建并进行 HSET 操作;如果域(field)已经存在于哈希表中,旧值将被覆盖。
-
字段值
- 设置一个具体的key-value
hset 键 值 - 设置多个具体的key-value
hmset 键 值1 值2 - 获取多个字段值
hmget 键 .... - 获取所有的字段
hgetall 键 - 删除指定字段
hdel 键 字段名
- 设置一个具体的key-value
-
字符长度
- 获取哈希的字符长度
hlen 键
- 获取哈希的字符长度
-
判断hash中的指定字段是否存在
hexists 键 字段名 -
自增自减
- 指定增量
hsetnx 键 字段 数 - 如果不存在则可以设置 如果存在则不能设置
使用场景:经常变动信息.做一些经常变动的信息
- 指定增量
@Resource
private RedisTemplate<Object,Object> redisTemplate;
@Test
void contextLoads() {
HashOperations hashOperations = redisTemplate.opsForHash();
hashOperations.put("user","name","admin");
hashOperations.put("user","age","18");
ListOperations listOperations = redisTemplate.opsForList();
listOperations.leftPush("sort",1);
listOperations.leftPush("sort",2);
listOperations.leftPush("sort",3);
Object sort = listOperations.leftPop("sort");
// 通过下标找联表数据,下标从零开始 往后找几位
List sort1 = listOperations.range("sort", 0, 2);
sort1.forEach(e -> {
System.out.println(e);
});
System.out.println(sort);
}
zSet(有序集合)
Redis Sorted Set 的使用场景与 Set 类似,区别是 Set 不是自动有序的,而 Sorted Set 可以通过用户额外提供一个优先级(Score)的参数来为成员排序,并且是插入有序,即自动排序。
如在使用 Zset 的时候需要额外的输入一个参数 Score,Zset 会自动根据 Score 的值对集合进行排序,我们可以利用这个特性来做具有权重的队列,比如普通消息的 Score 为 1,重要消息的 Score 为 2,然后工作线程可以选择按 Score 的倒序来获取工作任务。
- 添加一个值
zadd 键 值 - 显示全部数据 从小到大
zrangebyscore key min max( 负无穷 正无穷 -inf +inf) - 移除元素
- 移除有序集合中的指定元素
zrem 键 字段名 - 获取有序集合中的个数
zcard 键 - 获取指定区间的成员数量
zcount 键 数1 数2
- 移除有序集合中的指定元素
@Resource
private RedisTemplate<Object,Object> redisTemplate;
@Test
public void testZset() {
final String key = "lz";
ZSetOperations<Object,Object> zset = redisTemplate.opsForZSet();
zset.add(key, "hello", 1);
zset.add(key, "world", 6);
zset.add(key, "good", 4);
zset.add(key, "bye", 3);
Set<Object> zsets = zset.range(key, 0, 3);
for (Object v : zsets) {
System.out.println("zset-A value :"+v);
}
System.out.println("=======");
Set<Object> zsetB = zset.rangeByScore(key, 0, 3);
for (Object v : zsetB) {
System.out.println("zset-B value :"+v);
}
}