一、Redis概述
1.Redis是一个开源的key-value存储系统,支持的value类型相对很多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set有序集合)和hash(哈希类型)
2.数据都是保存在内存中
3.Redis会周期性的把更新的数据写入磁盘或把修改操作写入追加的记录文件。
4.实现master-slave(主从)同步
二、应用场景
- 缓存数据
用于存放以下特点的数据:
1)需要高频次访问
2)持久化数据访问较慢
3)用key查询
- 临时数据
用于存放以下的数据:
1)高频次
2)读写时效性高
3)临时性
4)用key查询
- 计算结果
用于存放以下数据:
1)高频次写入
2)高频次查询
3)总数据量不大
三、五大数据类型简介
Redis键(key)
语法 | 解释 |
keys* | 查看当前库所有key |
exits key | 判断某个key是否存在 |
type key | 查看你的key是什么类型 |
del | 删除指定的key数据 |
expire key 10 | 为给定的key设置过期时间 |
ttl | 查看还有多少秒过期 -1:永不过期 -2:已过期 |
select | 命令切换数据库 |
dbsize | 查看当前数据库的key数量 |
flushdb | 清空当前库 |
flushall | 通杀全部数据库 |
- 字符串(string)
语法 | 解释 |
set k v | 添加键值对 |
get k | 查询对应键值 |
append k v | 将给定的v追加到原值末尾 |
setnx k v | 只有key不存在时 设置key的值 |
incr k | 将key中存储的数字值增1(只能对数字值操作,如果为空新增值为1) |
decr k | 将key中存储的数字值减1 (同incr) |
incrby/decrby k 步长 | 将key中存储的数字值增减,自定义步长 |
mset k1 v1 k2 v2… | 同时设置一个或多个kv对 |
mgset k1 k2 k3 | 同时获取一个或多个v |
msetnx k1 v1 k2 v2 | 同时设置一个或多个kv对(仅当所有给定key都不存在) |
set k 过期时间 v | 设置键值的同时 设置过期时间单位秒 |
- List
语法 | 解释 |
lpush/rpush k v1 v2 v3 | 从左边/右边插入一个或多个值 |
lpop/rpop k | 从左边/右边吐出一个值(值在键在,值亡键亡) |
rpoplpush k1 k2 | 从k1列表右边吐出一个值插入到k2列表左边 |
lrange k start stop | 按照索引下标获得元素(从左到右) |
lrange mylist 0 -1 | 从0开始 -1表示获取所有 |
lindex k index | 按照索引下标获得元素 |
llen k | 获得列表长度 |
linsert before | after |
lrem k n v | 从左边删除n个v(从左到右) |
- set
语法 | 解释 |
sadd k v1 v2… | 将一个或多个 member 元素加入到集合 key 中,已经存在的 member 元素将被忽略 |
smembers k | 取出该集合的所有值 |
sismembers k v | 判断集合k是否为含有该v值 有1没有0 |
scard k | 返回该集合的元素个数 |
srem k v1 v2… | 删除集合中的某个元素 |
sinter k1 k2 | 返回两个集合的交集元素 |
sunion k1 k2 | 返回两个集合的并集元素 |
sdiff k1 k2 | 返回两个集合的差集元素(k1中的,不包含k2中的) |
- Hash
语法 | 解释 |
hset k field v | 给集合中的 键赋值 |
hget k1 field | 从k1集合field取出v |
hmset … | 批量设置hash的值 |
hexists | 查看哈希表 key 中,给定域 field 是否存在 |
hgetall | 列出该hash集合的所有field和value |
hincrby | 为哈希表 key 中的域 field 的值加上增量 1 -1 |
- Zsetz(sorted set)
语法 | 解释 |
zadd … | 将一个或多个 member 元素及其 score 值加入到有序集 key 当中。 |
zrange [WITHSCORES] | 返回有序集 key 中,下标在 之间的元素带WITHSCORES,可以让分数一起和值返回到结果集 |
zrevrange [WITHSCORES] | 逆序返回下标范围的数据 |
zrangebyscore key min max [withscores] [limit offset count] | 返回有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。有序集成员按 score 值递增(从小到大)次序排列。 |
zrevrangebyscore key max min [withscores] [limit offset count] | 同上,改为从大到小排列。 |
zincrby | 为元素的score加上增量 |
zrem | 删除该集合下,指定值的元素 |
四、两种持久化方式
- RDB
概述:在指定的时间间隔内将内存中的数据集快照写入磁盘, 也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里
备份是如何执行的
Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到 一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。 整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能 如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。
Fork
Fork的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等) 数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程
“写时复制技术” 一般情况父进程和子进程会共用同一段物理内存,只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程。
优势
适合大规模的数据恢复
对数据完整性和一致性要求不高更适合使用
节省磁盘空间
恢复速度快
劣势
1.Fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑
2.虽然Redis在fork时使用了写时拷贝技术,但是如果数据庞大时还是比较消耗性能。
3.在备份周期在一定间隔时间做一次备份,所以如果Redis意外down掉的话,就会丢失最后一次快照后的所有修改。
停止命令
动态停止RDB:redis-cli config set save "" #save后给空值,表示禁用保存策略
2.AOF
概述:以日志的形式来记录每个写操作(增量保存),将Redis执行过的所有写指令记录下来(读操作不记录), 只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis 重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作
AOF和RDB同时开启时,听谁的?
AOF和RDB同时开启,系统默认取AOF的数据(数据不会存在丢失)
Rewrite压缩
AOF采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制(默认开启), 当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩, 只保留可以恢复数据的最小指令集.可以使用命令bgrewriteaof
重写原理,如何实现重写
AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件最后再rename), 遍历新进程的内存中数据,每条记录有一条的Set语句。重写aof文件的操作,并没有读取旧的aof文件, 而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。
优势
1.备份机制更稳健 丢失数据概率更低
2.可读的日志文件 通过操作AOF文件 可以处理误操作
劣势
1. 比起RDB占用更多的磁盘空间。
2. 恢复备份速度要慢。
3. 每次读写都同步的话,有一定的性能压力。
4. 存在个别Bug,造成恢复不能。
主从复制
slaveof 成为某个实例的从服务器 例如:slaveof 127.0.0.1 6379
当主机挂掉时,选择另一个主机:salveof no one主从切换
哨兵模式:反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库
自定义的/myredis目录下新建sentinel.conf文件,名字绝不能错
sentinel monitor mymaster 127.0.0.1 6379 1
其中mymaster为监控对象起的服务器名称, 1 为至少有多少个哨兵同意迁移的数量
执行redis-sentinel /myredis/sentinel.conf