在整个NoSQL技术栈中MemCache、Redis、MongoDB被称为NoSQL三剑客。
命令参考地址:http://redisdoc.com
常用的一些命令:
1.基本操作
1) 切换数据库:
select 0
2) 查看数据库长度:
dbsize
2.key操作
1) 查找符合格式的Key:
KEYS *,KEYS ?(*代替多个字符,?代替一个字符)
2) 返回KEY对应的值的类型:
TYPE KEY
3) 把一组键值对数据移动到另一个数据库中:
MOVE KEY DB
4) 根据KEY进行删除,至少要指定一个KEY
DEL KEY [KEY ...]
5)检查指定的KEY是否存在。指定一个KEY时,存在返回1,不存在返回0。可以指定多个,返回存在的KEY的数量。
EXISTS KEY
6)在现有的KEY中随机返回一个
RANDOMKEY
7)重命名一个KEY,NEWKEY不管是否是已经存在的都会执行,如果NEWKEY已经存在则会被覆盖。
RENAME KEY NEWKEY
8)只有在NEWKEY不存在时能够执行成功,否则失败
RENAMENXKEYNEWKEY
9)以秒为单位查看KEY还能存在多长时间 -1表示永久有效
TTL KEY
10)给一个KEY设置在SECONDS秒后过期,过期会被Redis移除。
EXPIRE KEY SECONDS
11)移除过期时间,变成永久key
PERSIST KEY
3. String类型操作
1)给KEY设置一个String类型的值
EX参数用于设置存活的秒数。
PX参数用于设置存活的毫秒数。
NX参数表示当前命令中指定的KEY不存在才执行。
XX参数表示当前命令中指定的KEY存在才执行。
SET KEY VALUE[EX SECONDS] [PX MILLISECONDS] [NX|XX]
2)根据key得到值
GET KEY
3)直接返回字符串长度
STRLEN KEY
4)把指定的value追加到KEY对应的原来的值后面,返回值是追加后字符串长度
APPEND KEY VALUE
5)自增1(integer类型)
INCR KEY
6)自减1
DECR KEY
7)原值+INCREMENT
INCRBY KEY INCREMENT
8)原值-DECREMENT
DECRBY KEY DECREMENT
9)从字符串中取指定的一段
GETRANGE KEY START END
10)从offset开始使用VALUE进行替换
SETRANGE KEY OFFSET VALUE
11)设置KEY,VALUE时指定存在秒数
SETEX KEY SECONDS VALUE
12)(不存在时才能设置成功)
SETNX KEY VALUE
13)一次性设置一组多个键值对
MSET KEY VALUE [KEY VALUE ...]
14)一次性指定多个KEY,返回它们对应的值,没有值的KEY返回值是(nil)
MGET KEY [KEY ...]
15)一次性新建多个值(不存在时才能设置成功)
MSETNX KEY VALUE [KEY VALUE ...]
16)设置新值,同时能够将旧值返回
GETSET KEY VALUE
4.List类型操作
1)从左边添加数据
LPUSH key value [value ...]
2)右边添加数据
RPUSH key value [value ...]
3)根据list集合的索引打印元素数据
正着数:0,1,2,3,...
倒着数:-1,-2,-3,...
LRANGE key start stop
4)list集合的长度
LLEN key
5)从左边弹出一个元素。
弹出=返回+删除。
LPOP key
6)从右边弹出一个元素。
RPOP key
7)从source中RPOP一个元素,LPUSH到destination中
RPOPLPUSH source destination
8)根据索引从集合中取值
LINDEX key index
9)在pivot指定的值前面或后面插入value(pivot指的是list中具体的某个数据)
LINSERT key BEFORE|AFTER pivot value
10)只能针对存在的list执行LPUSH
LPUSHX key value
11)根据count指定的数量从key对应的list中删除value
LREM key count value
12)把指定索引位置的元素替换为另一个值
LSET key index value
13)仅保留指定区间的数据,两边的数据被删除
LTRIM key start stop
5.Set类型操作
1)向set集合添加数据
SADD key member [member ...]
2)查看set集合所有数据
SMEMBERS key
3)返回集合中元素的数量
SCARD key
4)检查当前指定member是否是集合中的元素
SISMEMBER key member
5)从集合中删除元素
SREM key member [member ...]
6)将指定的集合进行“交集”操作
集合A:a,b,c
集合B:b,c,d
交集:b,c
SINTER key [key ...]
7)取交集后存入 (如果存入相同key中数据会被覆盖)
SINTERSTORE destination key [key ...]
8)将指定的集合执行“差集”操作
集合A:a,b,c
集合B:b,c,d
A对B执行diff:a
相当于:A-交集部分
SDIFF key [key ...]
SDIFFSTORE destination key [key ...]
9)将指定的集合执行“并集”操作
集合A:a,b,c
集合B:b,c,d
并集:a,b,c,d
SUNION key [key ...]
SUNIONSTORE destination key [key ...]
10)把member从source移动到destination
SMOVE source destination member
11)从集合中随机返回count个数量的元素,count不指定就返回1个
SRANDMEMBER key [count]
12)从集合中随机弹出count个数量的元素,count不指定就弹出1个
SPOPkey [count]
6.Hash类型操作
1)添加数据
HSET key field value
2)查询一个key的所有数据
HGETALL key
3)查询一个key对应field的数据
HGET key field
4)查询一个key的数据个数
HLEN key
5)查询一个key的所有field
HKEYS key
6)查询一个key的所有value
HVALS key
7)判断一个key中是否存在指定的field
HEXISTS key field
8)删除一个key指定的field
HDEL key field [field ...]
9)给一个key的某个field对应的value增加increment值
HINCRBY key field increment
10)批量获取一个key的多个field所对应的value
HMGET key field [field ...]
11)批量添加一个key的多个field-value
HMSET key field value [field value ...]
12)在字段(field)不存在时添加数据
HSETNX key field value
7.ZSet类型操作
ZSet类型操作
1)添加数据
ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
· XX:仅仅更新存在的成员,不添加新成员。
· NX:不更新存在的成员。只添加新成员。
· CH:修改返回值为发生变化的成员总数,原始是返回新添加成员的总数 (CH 是changed的意思)。更改的元素是新添加的成员,已经存在的成员更新分数。所以在命令中指定的成员有相同的分数将不被计算在内。注:在通常情况下,ZADD返回值只计算新添加成员的数量。
·INCR:当ZADD指定这个选项时,成员的操作就等同ZINCRBY命令,对成员的分数进行递增操作
2)在指定范围内返回数据([WITHSCORES]带上分数返回)
ZRANGE key start stop [WITHSCORES]
3)查询key对应的数据个数
ZCARD key
4)返回对应数据的分数
ZSCORE key member
5)给某个元素增加分数
ZINCRBY key increment member
6)在分数的指定区间内返回数据(Limit+返回结果的下标位置+返回个数)
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
7)先对分数进行升序排序,返回member的排名
ZRANK key member
8)先对分数进行降序排序,返回member的排名
ZREVRANK key member
9)删除元素
ZREM key member [member ...]
8.Redis持久化机制
Redis工作时数据都存储在内存中,万一服务器断电,则所有数据都会丢失。针对这种情况,Redis采用持久化机制来增强数据安全性。
1)RDB
每隔一定的时间把内存中的数据作为一个快照保存到硬盘上的文件中。Redis默认开启RDB机制。
优势:适合大规模的数据恢复,速度较快
劣势:如果宕机的话会丢失最后一次快照后的所有修改,不能绝对保证数据的高度一致性和完整性。Fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑,但上述成立有条件,Linux也有优化手段
1)基于默认配置
save 900 1
save 300 10
save 60 10000
2)使用保存命令
save或bgsave
save会阻塞当前进程用来将数据落盘,bgsave会在后台开启一个进程来将数据落盘。
3)使用flushall命令会清空所有库,这个命令也会产生dump.rdb文件,但里面是空的,没有意义
4)服务器关闭,如果执行SHUTDOWN命令让Redis正常退出,那么此前Redis就会执行一次持久化保存。
相关配置
RDB机制能够保证数据的绝对安全吗?不能,如果宕机了数据只能恢复上次备份的数据,上次备份的到宕机之前的数据无法保存
AOF
机制描述:根据配置文件中指定的策略,把生成数据的命令保存到硬盘上的文件中。
优势:选择appendfsync always方式运行时理论上能够做到数据完整一致,但此时性能又不好。文件内容具备一定可读性,能够用来分析Redis工作情况。
劣势:持久化相同的数据,文件体积比RDB大,恢复速度比RDB慢。效率在同步写入时低于RDB,不同步写入时与RDB相同。
配置项 取值 作用
appendonly yes 启用AOF持久化机制
no 禁用AOF持久化机制[默认值]
appendfilename "文件名" AOF持久化文件名
dir Redis工作目录路径 指定存放持久化文件的目录的路径。注意:这里指定的必须是目录不能是文件名
appendfsync always 每一次数据修改后都将执行文件写入操作,缓慢但是最安全。
everysec 每秒执行一次写入操作。折中。
no 由操作系统在适当的时候执行写入操作,最快。(写入aof文件,不等待磁盘同步)
AOF重写
可以通过修改配置参数来进行重写,vim /opt/module/redis/redis.conf
auto-aof-rewrite-percentage --100文件体积增大100%时执行AOF重写
auto-aof-rewrite-min-size 64mb --文件体积增长到64mb时执行AOF重写
实际工作中不要进行频繁的AOF重写,因为CPU资源和硬盘资源二者之间肯定是CPU资源更加宝贵,所以不应该过多耗费CPU性能去节省硬盘空间。可以把大小设置300或靠上,64mb调大5g就差不多
持久化文件损坏修复
Redis服务器启动时如果读取了损坏的持久化文件会导致启动失败,此时为了让Redis服务器能够正常启动,需要对损坏的持久化文件进行修复。这里以AOF文件为例介绍修复操作的步骤。
第一步:备份要修复的appendonly.aof文件
第二步:执行修复程序
bin/redis-check-aof --fix ./appendonly.aof
第三步:重启Redis
注意:所谓修复持久化文件仅仅是把损坏的部分去掉,而没法把受损的数据找回。
RDB和AOF并存
Redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整
RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。那要不要只使用AOF呢?作者建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份)、快速重启,而且不会有AOF可能潜在的bug,留着作为一个以防万一的手段。
9.Redis事务控制
命令名 作用
MULTI 表示开始收集命令,后面所有命令都不是马上执行,而是加入到一个队列中。
EXEC 执行MULTI后面命令队列中的所有命令。
DISCARD 放弃执行队列中的命令。
WATCH “观察“、”监控“一个KEY,在当前队列外的其他命令操作这个KEY时,放弃执行自己队列的命令
UNWATCH 放弃监控一个KEY
1)命令队列执行失败的两种情况
加入队列时失败
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set age 20
QUEUED
127.0.0.1:6379> incr age
QUEUED
127.0.0.1:6379> incr age www
(error) ERR wrong number of arguments for 'incr' command
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
执行队列时失败
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set age 30
QUEUED
127.0.0.1:6379> incrby age 5
QUEUED
127.0.0.1:6379> incrby age 5
QUEUED
127.0.0.1:6379> incrby age ww
QUEUED
127.0.0.1:6379> incrby age 5
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) (integer) 35
3) (integer) 40
4) (error) ERR value is not an integer or out of range
5) (integer) 45
127.0.0.1:6379> get age
"45"
加入队列失败是无法执行MULTI后面命令队列中的所有命令的,执行队列失败会将成功的执行,错误的无法执行,Redis是不支持回滚的
Redis为什么不支持回滚?
官方解释如下:
如果你有使用关系型数据库的经验,那么“Redis在事务失败时不进行回滚,而是继续执行余下的命令”这种做法可能会让你觉得有点奇怪。以下是这种做法的优点:
1)Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编译错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。
2)因为不需要对回滚进行支持,所以Redis的内部可以保持简单且快速。有种观点认为 Redis处理事务的做法会产生bug,然而需要注意的是,在通常情况下,回滚并不能解决编程错误带来的问题。举个例子,如果你本来想通过 INCR 命令将键的值加上1,却不小心加上了2,又或者对错误类型的键执行了INCR,回滚是没有办法处理这些情况的。
Watch
在使用WATCH命令监控一个KEY后,当前队列中的命令会由于外部命令的执行而放弃,这是乐观锁的体现。
1)悲观锁:认为当前环境非常容易发生碰撞,所以执行操作前需要把数据锁定,操作完成后释放锁,其他操作才可以继续操作。(不允许其他队列修改)
2)乐观锁:认为当前环境不容易发生碰撞,所以执行操作前不锁定数据,万一碰撞真的发生了,那么放弃自己的操作。(会允许其他队列的修改)
10. Redis主从复制机
读写分离的好处
性能优化:主服务器专注于写操作,可以用更适合写入数据的模式工作;同样,从服务器专注于读操作,可以用更适合读取数据的模式工作。
强化数据安全,避免单点故障:由于数据同步机制的存在,各个服务器之间数据保持一致,所以其中某个服务器宕机不会导致数据丢失或无法访问。从这个角度说参与主从复制的Redis服务器构成了一个集群。
搭建步骤:
Redis集群在运行时使用的是同一个可执行文件,只是对应的配置文件不同。
daemonize yes
dir /opt/module/redis/cluster
需要修改的参数:
具体的步骤:
第一步:创建/opt/module/redis/cluster目录
第二步:把原始未经修改的redis.conf复制到/opt/module/redis/cluster目录
第三步:把/opt/module/redis/cluster目录下的redis.conf复制为redis6000.conf
第四步:按照既定计划修改redis6000.conf中的相关配置项
‘daemonize yes’ dir port dbfilename logfile pidfile
第五步:复制redis6000.conf为redis7000.conf cp redis6000.conf ./redis7000.conf
第六步:修改redis7000.conf中的相关配置项
port dbfilename logf ile pidfile
第七步:复制redis6000.conf为redis8000.conf
第八步:修改redis8000.conf中的相关配置项
port dbfilename logfile pidfile
启动:
#服务
bin/redis-server ./cluster/redis6000.conf
bin/redis-server ./cluster/redis7000.conf
bin/redis-server ./cluster/redis8000.conf
#客户端
bin/redis-cli -p 6000
bin/redis-cli -p 7000
bin/redis-cli -p 8000
查看主从关系
127.0.0.1:6000> info replication
# Replication
role:master
connected_slaves:0
设定主从关系
SLAVEOF 127.0.0.1 6000
取消主从关系
SLAVEOF NO ONE
初步测试:
测试1:在主机写入数据,在从机查看
测试2:在从机写入数据报错。配置文件中的依据是:slave-read-only yes
测试3:主机执行SHUTDOWN看从机状态
测试4:主机恢复启动,看从机状态
测试5:从机SHUTDOWN,此时主机写入数据,从机恢复启动查看状态。重新设定主从关系后看新写入的数据是否同步。
此模式有弊端:
1.master挂掉之后,集群没有写的能力
2.从机挂掉之后,不会自动加入集群
由此可以用哨兵模式来解决此弊端
哨兵模式
作用:通过哨兵服务器监控master/slave实现主从复制集群的自动管理。
相关概念:
1)主观下线:1台哨兵(sentinel)检测到某节点服务器下线。
2)客观下线:认为某个节点服务器下线的哨兵服务器达到指定数量。这个数量后面在哨兵的启动配置文件中指定。
配置方式:
简单起见我们只配置一台哨兵。我们所需要做的就是创建一个哨兵服务器运行所需要的配置文件。
vim /opt/module/redis/cluster/sentinel.conf
格式sentinel monitor 为主机命名 主机IP 主机端口号 将主机判定为下线时需要Sentinel同意的数量
例子sentinel monitor mymaster 127.0.0.1 6000 1
启动哨兵:
bin/redis-server cluster/sentinel.conf --sentinel
当我们将前面设置6000、7000、8000三台集群开起来,将主机设置为6000,如果从机有一个挂掉了,再次重启从机仍然会选择6000为主机,如果6000关掉了,那么会在从机里选出一个master
日志:
+sdown master mymaster 127.0.0.1 6379 【主观下线】
+odown master mymaster 127.0.0.1 6379 #quorum 1/1【客观下线】
……
+vote-for-leader 17818eb9240c8a625d2c8a13ae9d99ae3a70f9d2 1【选举leader】
……
+failover-state-send-slaveof-noone slave 127.0.0.1:6381 127.0.0.1
6381 @ mymaster 127.0.0.1 6379【把一个从机设置为主机】
-------------挂掉的主机又重新启动---------------------
-sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1
6381【离开主观下线状态】
+convert-to-slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster
127.0.0.1 6381【转换为从机】