Redis特点:
- 数据操作基于内存,速度快;
- 单线程执行客户端请求,避免并发问题;
- 支持持久化,防止数据丢失;
- 数据类型丰富,应用场景多;
- 支持高可用架构搭建。
通用信息:
- 一个redis数据库服务器默认16个数据库,类似数组下表从0开始,初始默认使用数据库0;
- dbsize:查看当前数据库key的个数;
- select index:选择数据库;
- flushdb:清空当前数据库;
- flushall:清空所有数据库;
- redis服务器默认没有密码,可以在redis.conf文件中进行设置:requirepass 密码;该密码为所有数据库共享。
常用数据类型及操作:
String:字符串
- set key value;
- getset key value;
- expire key value;
- get key;
- setnx key value;
- strlen key;
- incr/decr key;
- exists key;
- rename key newKey;
- keys pattern(线上key过多导致长时间阻塞);
- del key;
- ttl key;
- type key;
Hash:字典、map
- hset key field1 value1 field2 value2...;
- hget key field;
- hgetall key;
- hexists key field;
- hkeys key;
- hvals key;
- hlen key;
- hdel key field;
- hstrlen key field;
List:双向队列
- lpush/rpush key value;
- lpop/rpop key value;
- llen key;
- lrange key start end;
- blpop/rlpop key timeout:阻塞式弹出第一个/最后一个元素
- lindex key index:获取key对应列表index索引位置的元素
Set:无序无重复元素集合、value为null的hashmap
- sadd key value1 valu2 ...;
- scard key:获取元素个数;
- smembers key;
- sismember key value;
- sscan key cursor [match pattern] [count count]:基于游标迭代集合,下一次迭代传入返回的游标0即可
- sdiff set1 set2:获取set1存在,set2中不存在的元素
- sdiffstore target set1 set2:获取set1存在,set2中不存在的元素并存入target中
- sinter set1 set2:获取交集
- sinterstore target set1 set2:获取交集并存储
- smove source target member:从source移动member至target
- srem key member [...]:删除元素
- sunion set1 set2:合并,并不会改变两个集合本身
- sunionstore target set1 set2:合并并存储
Sorted Set:有序集合,hashmap + 跳跃表
- zadd key score1 member1 [score2 member2...];
- zcard key;
- zrange key start stop [withscore]:返回索引在start-stop内的元素;
- ZRANGEBYSCORE key min max [withscores] [limit offset num]:返回在指定分数范围内的成员
- ZRANGEBYLEX key [min [max [LIMIT offset count]:返回分数相同,值在min-max内的成员
- zcount key min max:计算key对应集合中索引在min-max中的元素个数;
- ZINCRBY key increment member:增加分数;
- zrank key member:确定member在key中的位置
- zrem key member1 [member2...];
- ZREMRANGEBYSCORE key min max:删除分数在在min-max内的成员
- ZREVRANGEBYSCORE key max min:逆序获取score在max-min内的成员
- ZSCAN key cursor [MATCH pattern] [COUNT count] 增量迭代排序元素集和相关的分数
Hyperloglog:基数计算
- PFADD key value1 value2 ...:添加指定元素到 HyperLogLog 中
- PFCOUNT key:获取基数值
- PFMERGE target key1 key2:合并
pub/sub:发布订阅
- SUBSCRIBE channel1 channel2 ...:订阅
- PUBLISH channel message:发布
Bloom Filter:布隆过滤器(位数组 + hash函数)
- bf.add key value1 value2 ...
- bd.exists key value
管道
Redis是使用
C/S
模型和Request/Response协议的TCP服务器,客户端向服务端发送查询请求时以阻塞方式从socket套接字中读取服务端响应。当客户端需要连续执行许多请求时,频繁的建立与断开连接会严重影响性能。使用管道操作通过将多个请求以一次网络IO发送至服务器,然后一次性获取每一条指令的结果,可以减少网络IO的开销。
redisTemplate.executePipelined(new RedisCallback<Object>() {
@Nullable
@Override
public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
redisConnection.openPipeline();
for (int i = 0;i < 100000;i++) {
redisConnection.set(("test-key:" + i).getBytes(), ("test-value:" + i).getBytes());
}
return null;
}
});
事务
redis中的事务保证一个事务中的指令序列执行,但无法实现事务回滚。
- watch key:观察某个key添加乐观锁,如果监控过程中该key变其他客户端修改,则事务失效。
- multi:开启事务
- ...(多条执行语句)
- exec:提交事务
- discard:回滚事务
- unwatch:取消乐观锁
数据清除策略
当数据到达最大内存限制时(maxmemory),redis根据maxmemory-policy配置策略,调用
LRU
算法来决定具体行为。可以在redis.conf进行配置:maxmemory-policy noeviction/allkey-lru...
- noeviction:不删除策略,达到最大内存限制时刻,如果需要更多内存,直接返回错误信息;
- allkey-lru:所有key通用,优先删除最近最少使用的key(LRU);
- volatile-lru:只限于设置了expire的部分,优先删除最近最少使用的key;
- allkey-random:所有key通用,随机删除一部分key;
- volatile-random:只限于设置了expire部分,随即删除一部分key
- volatile-ttl:只设置了expire的部分;优先删除剩余时间短的key
持久化
redis操作基于内存带来了性能上的优势,为防止服务器宕机导致数据丢失,需要在特定的时刻进行数据持久化操作。
RDB:通过在指定时刻生成内存快照
的方式实现持久化。该选项自动开启。
redis.conf中默认配置
快照生成策略
为:
- save 900 1:900秒内只有有一个键更改进行快照
- save 300 10:300秒内至少有10个键被修改则进行快照
- save 60 10000:60秒内至少有一千个键被修改则进行快照
修改为:
save " "
可以关闭RDB;
快照文件位置配置项默认为:dir ./
,名称配置项默认为dbfilename dump.rdb
;
RDB的生成:
(1)触发时机:自动触发、save(导致主线程阻塞)、bgsave;
(2)生成操作:
- redis调用系统函数
fork()
创建一个子进程进行快照生成,该进程不会阻塞主进程处理客户端请求;- fork出的子进程将内存中的数据集写入一个临时的RDB文件;
- 当子进程完成对临时RDB文件的写入时,redis 用新的临时RDB 文件替换原来的RDB 文件,并删除旧 RDB 文件。
注:RDB文件生成的过程中采用写时复制的策略,即RDB中保存的是执行fork()函数瞬间的数据集。
(3)优点:
- 文件内部数据紧凑,适合做数据备份与灾难恢复(
恢复时只需要将对应的RDB文件放入指定的目录重启服务即可(aof必须关闭)
);fork()
出的子进程不会对主进程的执行有任何影响;- 大数据集恢复速度快。
(4)缺点:
- 由于RDB文件只有在到达
save point(保存点)
时才会生成,一旦故障停机,将会丢失上一个RDB文件生成到停机时刻内的所有数据;save point
设置太频繁会导致CPU资源紧张;设置跨度较长又会导致宕机丢失数据较多。
AOF:Append only file
AOF
通过记录对服务器执行的写命令
实现持久化。AOF选项默认关闭:
appendonly no
,可修改为yes
开启AOF功能;AOF文件名称配置项为
appendfilename "appendonly.aof"
;AOF文件写入触发策略:
- appendfsync always:所有写命令都会触发
- appendfsync everysec(
默认
):每个一秒写入- appendfsync no:不同步
AOF恢复:只需要将生成的aof文件放置在配置的路径下重启服务器即可;
AOF文件重写机制:
auto-aof-rewrite-percentage
: 100 (当aof文件大小是上次rewrite后的一倍时触发重写)auto-aof-rewrite-min-size
:64mb (aof文件触发重写的最小值,通常设置为3GB)AOF重写:
AOF的工作原理是将写操作追加到文件中,文件的冗余内容会越来越多。所以添加了RDB重写机制:当AOF文件的大小超过所设定的阈值时,Redis 会fork出一条新进程,读取内存中的数据,并重新写到一个临时文件中(没有读取旧文文件),最后替换旧的aof文件。
优点:数据的完整性和一致性更高。
缺点:因为AOF记录的内容多,文件会越来越大,数据恢复也会越来越慢。
注:在实际开发中,可能因为某些原因导致appendonly.aof 文件格式异常,从而导致数据还原失败,可以通过命令redis-check-aof --fix appendonly.aof 进行修复 。
AOF与RDB的混合使用(默认开启)
- AOF根据配置规则在后台自动重写aof文件,也可以人为执行命令
bgrewriteaof
重写AOF。 aof与rdb混合使用时,Redis在重启时,先重写rdb到内存,然后在重写aof到内存,重启效率高,还能减少数据的丢失。- 配置项:
aof-use-rdb-preamble yes
。