NoSQL四大分类
KV键值对:
redis、tair、memecache
文档型数据库
MongoDB、CouchDB
列存储数据库
HBase、分布式文件系统
图关系数据库
存放的不是图形,是关系
Neo4j、InfoGrid
安装:window
直接下载解压、修改环境变量即可
默认端口:6379
安装:linux
1、下载安装包
2、解压安装包
3、make
4、复制一份配置文件 (不使用默认的配置文件启动redis)
5、修改配置文件使用守护线程
6、启动redis redis-server redis.config
redis-cli -p 6379
-p:表示端口号
7、使用ps -ef|grep redis
查看进程
8、使用shutdown关闭
Redis benchmark测试
benchmark性能测试工具参数表
测试样例:
redis-benchmark -h localhost -p 6379 -c 100 -n 100000
基本命令
redis 共16个数据库,默认使用第0个
#切换数据库 使用select num 例如:selelct 3
dbsize 查看数据库的大小
keys * 查看所有的key
flushdb 清空数据库
flushall 清空所用的数据库
set key value 设置 key 的值为value -- set name fang
get key 获取 key 的值 -- get name
exists key 查询是否存在为 key 的键 -- exists fang
keys * 查询所有的key -- keys *
move key db 将 key 移动到其他的数据库 -- move fang 1
expire key 设置 key 的过期时间(秒) -- expire fang 10
type key 查看 key 的类型 -- type fang
redis是单线程的,redis基于内存操作,CPU不是redis性能瓶颈,瓶颈是机器的内存和网络带框
redis单线程还是这么快的原因:redis将所有的数据全部放在内存中的,避免了多线程的CPU上下文切换,没有CPU上下文切换所以效率是最高的。
五大数据类型
String
set name fang
append key value 在键 key 后追加一个值,如果key不存在,相当于set key
strlen key 返回 key 字符串的长度
incr key 将 key 的值加1,自增1
incrby key value 将key的值 加 value 的步长 -- incrby num 10
decr key 将key 的值减1,自减1
decrby key value 将key 的值减去value 的步长 -- derby num 10
getrange key start end 获取 key 的start到end 的子串 getrange name 0 1 -> fa 是闭区间[0, 1]
setrange key offset value 将key的中字符进行替换 setrange name 1 xx -> fxxg
setex key seconds value 设置 key的过期时间
setnx key value 如果不存在,再创建key,如果存在则创建失败
mset key value [key value ...] 设置多个key value键值对
mget key [key ...] 获取多个key
msetnx key value [key value ...]原子操作要么全成功,要么全失败
# 设置对象
set user:1:name fang
getset key value 先获取值然后在设置值,若一开始为空,则返回空
List
lpush key value [value ...] 将一个值或者多个值插入到列表的头部(左边)
lpop key 取出列表头部的数据(左边)
rpush key value [value ...] 将一个值或者多个值插入到列表的尾部(右边)
rpop key 取出列表尾部的数据(右边)
lrange key begin end 获取列表的中数据的范围
lindex key index 获取列表下标为index 的值
llen key 获取列表的长度
lrem key count value 移除列表中值为value的count个数
ltrim key begin end 截取指定的列表的数据,改变原有的list,留下的是截取之后的list
rpoplpush list otherlist 将list尾部的数据取出放入otherlist的头部
lset key index value 将列表的index位设置成value
linsert key before|after prevalue value 将value插入到list中的prevalue之前或者之后
Set
sadd key value [value ...] 添加set元素
smembers key 查看set中的元素
sismember key value 查看value是否是set中的元素
scard key 获取set中的个数
srem key value [value ...] 移除set中的元素
srandmember key count 获取set中随机的count个元素
spop key [count] 随机删除set中的元素
smove set otherset value 将set中指定的value移动到otherset
sdiff set otherset 查看set和otherset中之间的差集
sinter set otherset 查看set和otherset的交集
sunion set otherset 查看set和otherset的并集
ZSet
zadd key score member [score member...] 设置zset的值
zrange key begin end 获取zset从begin到end 的值,闭区间[begin, end]
zrangebysocre key -inf +inf 获取zset中按照score从负无穷到正无穷排序的值
zrevrangebyscore key +inf -inf 获取zset中按照score从正无穷到负无穷排序的值
zrem key member 删除指定的member的值
zcard key 获取zset中的元素个数
zcount key min max 获取zset中min到max的值数量,闭区间[min, max]
Hash
hset key field value 设置hash的字段和值
hget key field 获取hash的字段为field的值
hmset key field value [field value ...] 设置多个字段的值
hmget field [field ...] 获取多个字段的值
hgetall key 获取所有的hash的键值对
hdel key field [field ...] 删除hash中的字段
hlen key 获取hash 的字段数量
hexists key field 判断hash中存在field字段
hkeys key 获取hash中所有的key
hvals key 获取hash中所有的value
hincrby key field increment 将hash中的field字段的值增加increment的步长
hsetnx key field value 设置hash中的field字段,若存在则不能设置,若不存在则设置
三种特殊数据类型
geospatial
geoadd key lng lat member [lng lat member ...] 添加元素信息
geodist key member member [unit] 查询一个key中两个成员之间的距离默认米, unit可以使用的单位m/km/ft/mi
geohash key member [member ...] 获取成员的hash值
geopos key member [member...] 查询key中member的经纬度
georadius key lng lat radius m/km/ft/mi 以给定的经纬度为中心找到key中的成员
georadiusbymember key member radius m/km/ft/mi 以某个元素为中心半径为radius的key中的其他成员
其余操作可以相当于zset中的操作类似于 zrange/zrem等等
hyperloglog
基数统计算法:使用场景统计网站的访问人次
pfadd key element [element ...] 添加原始
pfcount key [key ...] 统计key中基数的个数
pfmerge key sourcekey [key...] 合并多个元素到key中
bitmaps
setbit key offset value 设置bit的数值
getbit key offset 获取bit的值
bitcount key 统计key中数据值为1 的个数
事务
redis单条命令是保存原子性的,但是事务不保证原子性!
开始事务 -> multi
添加命令 -> set name fang
执行命令 -> exec
discard 将multi之后写的命令全部抛弃,并结束事务
事务中异常问题:
编译异常:命令书写错误 -> 事务中所有的命令都不执行
运行时异常:命令格式正确,运行错误 -> 出现的问题其他正确的命令会正常执行,错误的命令执行失败。
乐观锁,悲观锁:
watch key 设置获取乐观锁
unwatch 解锁
Jedis
1、创建maven工程
2、添加maven的jar依赖 Jedis
3、new Jedis(“localhost”).ping() 返回pong则连接成功!
redis指令 对应 jedis 方法
Jedis jedis = new Jedis("localhost");
jedis.set("name", "fang");
jedis.get("name");
SpringBoot整合
1、建springboot项目,加入依赖
2、使用RedisTemplate进行操作
@Autowired
RedisTemplate redisTemplate;
3、添加一个配置类,修改默认RedisTemplate的序列化方式 (默认的template的key为object)
@Component
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setKeySerializer(stringRedisSerializer);
template.setValueSerializer(fastJsonRedisSerializer);
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
redis.conf 配置
windows 配置文件为 reids.windows.conf
单位
大小写不敏感
包含其他文件
包含其他的配置文件
# include .\path\to\local.conf
# include c:\path\to\other.conf
网络
bind 127.0.0.1 绑定的ip
protected-mode yes 保护设置
port 6379 端口
timeout 0 超时
通用
daemonize no 是否开启守护线程
supervised no
pidfile /var/run/redis.pid
# debug (a lot of information, useful for development/testing)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably)
# warning (only very important / critical messages are logged)
loglevel notice 日志级别
logfile "" 日志的文件位置
databases 16 数据库的数量,默认16个数据库
快照
持久化
save 900 1 若果900秒内,至少有1个key进行了修改,我们进行持久化操作
save 300 10 若果300秒内,至少有10个key进行了修改,我们进行持久化操作
save 60 10000 若果60秒内,至少有10000个key进行了修改,我们进行持久化操作
stop-writes-on-bgsave-error yes 持久化出错,是否还需要继续工作
rdbcompression yes 是否压缩rdb文件,消耗cpu资源
rdbchecksum yes 保存rdb文件时,进行错误校验
dbfilename dump.rdb rdb文件
dir ./ rdb文件保存的目录,默认当前目录
复制
slaveof <masterip> <masterport> 配置从机
masterauth <master-password> 连接主机的密码配置
安全
requirepass 123456 配置文件设置密码
config get requirepass 命令查看密码
config set requirepass 123456 命令设置密码
auth 123456 密码登录
限制
maxclients 10000 最大客户端的数量
maxmemory <bytes> 配置最大的内存容器
# volatile-lru -> remove the key with an expire set using an LRU algorithm
# allkeys-lru -> remove any key according to the LRU algorithm
# volatile-random -> remove a random key with an expire set
# allkeys-random -> remove a random key, any key
# volatile-ttl -> remove the key with the nearest expire time (minor TTL)
# noeviction -> don't expire at all, just return an error on write operations
maxmemory-policy noeviction 内存达到上限之后的处理策略
APPEND ONLY 模式 aof配置
appendonly no 默认是不开启aof模式,默认使用rdb持久化
appendfilename "appendonly.aof" 持久化文件的名字aof
# appendfsync always 每次修改都会sync,消耗性能
appendfsync everysec 每秒执行一次sync,可能会丢失1s对数据
# appendfsync no 不执行sync,操作系统自己同步数据,速度快
Redis 持久化
RDB
触发机制:
1、save 规则满足的情况下,会自动触发rdb规则
2、执行flushall 命令,也会触发rdb规则
3、退出redis,也会产生rdb文件
恢复rdb文件,只需存放在启动目录即可
优点:
1、适合大规模的数据恢复
2、对数据的完整性不高
缺点:
1、需要一定的时间间隔进程操作!如果redis意外的宕机了,最后一次的修改数据就没有了
2、fork进程的时候,会占用一定的内存空间
AOF (Append Only File)
记录所有的命令,恢复的时候直接把对应的文件中的命令执行一遍即可。(记录写的操作,读操作不记录)
默认不开启,需要手动配置
修改的配置文件将appendonly 改为 yes
appendonly yes
如果 aof 文件有错误,redis是启动不起来的,需要使用redis提供的 redis-check-aof 进行修复aof文件
redis-check-aof --fix 文件名 修复命令
优点:
1、每次修改都同步,文件的完整性会更好!
2、每秒同步一次,可能会丢失一秒的数据
3、从不同步,效率最高
缺点:
1、相对于数据文件来说,aof文件要大于rdb文件,修复的速度也比rdb慢
2、aof 运行效率也要比rdb慢,所以redis默认配置就是rdb的持久化
Redis 发布订阅
先订阅,再发消息
client1:
subscribe fang 订阅 fang 频道
client2:
publish fang hello 向 fang 频道发消息 hello
Redis 主从复制、读写分离
数据的复制只能是单向的,主机写为主,从机读为主
主从复制的作用
- 数据冗余
- 故障恢复
- 负载均衡
- 高可用基石
环境配置
redis默认为主库,则只需要配置从库
查看当前库的信息:
127.0.0.1:6379> info replication
# Replication
role:master # 角色 master
connected_slaves:0 # 没有从机
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
复制配置文件,修改配置文件中的信息
- 端口号
- pid 名
- 日志文件名 log
- 备份库名 dump.rdb
- 启动修改之后的配置文件的 redis 服务
从机中配置
slaveof 主机ip 端口 配置从机
127.0.0.1:6381> slaveof 127.0.0.1 6379
OK
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
主机可以写,从机不能写只能读
主机断开连接,从机依然可以使用,但是不能进行写操作,如果主机正常了,从机依然可以正常连接到主机
127.0.0.1:6381> set name fang
(error) READONLY You can't write against a read only slave.
127.0.0.1:6381>
复制的方式
- 全量复制: 全部同步
- 增量复制: 主机修改的命令依次传递给从机完成同步
只要重新连接主机就会产生一次 全量复制
哨兵模式(自动选举)
手动修改命令:
slaveof no one 从机将自己变成主机
哨兵配置:
1、配置哨兵配置文件sentinel.conf
sentinel monitor myredis 127.0.0.1 6379 1 # 监控127.0.0.1的端口为6379
2、启动哨兵
redis-sentinel sentinel.conf
主机宕机情况:
1、主机宕机,哨兵会投票选取从机中得票最多的一个作为主机
2、原来的主机恢复正常,将会成为现有主机的从机
优点:
1、基于主从复制
2、主从切换,故障转移
3、哨兵模式是主从模式的升级,手动到自动
缺点:
1、redis不好在线扩容
2、哨兵模式配置麻烦
Redis 缓存穿透和雪崩
缓存穿透
简单理解:用户访问的数据在缓存和数据库中都没有数据,恶意的大量数据访问造成数据库崩溃。
解决方案:
1、布隆过滤器
2、缓存空对象
缓存击穿
简单理解:一个key对应大量的请求,当此时key失效则出现大量的请求打到数据库。
解决方案:
1、设置热点数据永不过期
2、分布式锁
缓存雪崩
简单理解:缓存集体过期 或 redis 宕机,造成大量数据打到数据库
解决方案:
1、redis 高可用。异地多活
2、限流降级
3、数据预热