1.redis压力测试
# 本地服务器测试 端口号6379 100并发 10万连接
redis-benchmark -h localhost -p 6379 -c 100 -n 100000
2.Redis常用命令
# hash 哈希基本操作
hset user:id:1 name zhangsan #只能添加一个值 hset [user:id:1] [键] [值]
hget user:id:1 id #获取一个值 hget [user:id:1] [键]
hmset user:id:1 id 1 name zhangsan age 50 # 批量设置
hmget user:id:1 id name age #批量获取
hgetall user:id:1 #获取所有内容
pkill redis-server #重启redis
# 输入密码
redis-cli -a password #exit关闭后 连接redis的时候输入设置的密码验证
auth password #开启后则输入
3.Redis数据库
Redis一共有16个数据库 分别是:0-15
select [num] #切换数据库
dbsize #返回当前数据库键的个数
flushdb #清空当前数据库里面的键
flushall #清空所有数据库中的键
4.键值基本操作
keys * #获取所有key
keys [name]* #获取name前缀的所有键
exists [key] #判断key是否存在 存在返回1 不存在返回0
move [key] [db-num] #移动key到另一个数据库
del [key] #删除指定的一个键 name键名
expire [key] [seconds] #设置key过期时间(单位秒)
ttl [key] #获取key过期时间 获取不存在的key返回-2
type [key] #查看key的类型
5.String操作
####################################################################
set [key] [key-value] #设置键值
get [key] #获取键值
setex [key] [seconds] [key-value] #设置键值及过期时间
setnx [key] [key-value] #如果key不存在创建成功,存在返回0创建失败
mset [key] [key-value] [key1] [key1-value] #一次性设置多个键值
mget [key] [key1] #获取多个键值
####################################################################
incr [key] #键值自增1
decr [key] #键值自减1
incrby [key] [num] #键值自增num
decrby [key] [num] #键值自减num
####################################################################
getrange [key] [start] [end] #获取指定位置字符串 start开始位置 end结束位置
getrange [key] 0 -1 #获取所有字符串
setrange [key] [start] [value] #替换指定位置开始的字符串
getset [key] [key-value] #先获取原值再设置,如果值不存在返回nil,值存在返回值再设置新值
append [key] [key-value] #在字符串后面插入字符,返回字符串总长度,如果key不存在,则插入一条记录
strlen [key] #获取字符串长度
####################################################################
6.list链表
####################################################################
lpush [key] [value] #创建一个链表,从头部开始插入数据
rpush [key] [value] #创建一个链表,从尾部开始插入数据
lset [key] [index] #更新链表指定下标值,如果下标index不存在会报错
linsert [key] [before/after] [value] [value1] #指定位置插入值,before在value值前面插入value1
####################################################################
lrange [key] [start] [end] #查看链表数据,start开始下标,end结束下标
lrange [key] 0 -1 #查看链表所有数据
lindex [key] [num] #获取链表指定下标值,下标不存在返回nil
llen [key] #获取链表长度
ltrim [key] [start] [end] #截取链表数据,start开始下标,end结束下标(返回截取后的链表)
rpoplpush [key] [key1] #截取key链表最后数据插入到key1链表中
####################################################################
lpop [key] #移除链表第一个元素
rpop [key] #移除链表最后一个元素
lrem [key] [num] [value] #移除指定的值,num指定移除个数,value链表值(精确匹配)
####################################################################
7.set集合
####################################################################
sadd [key] [value] #添加集合,value重复则添加失败,返回0,成功返回1
smembers [key] #查看集合里面的所有元素
scard [key] #获取集合元素个数
####################################################################
sismember [key] [value] #判断value是否在key集合中,存在返回1,不存在则返回0
srandmember [key] [num] #获取集合里面的随机num个值
spop [key] [num] #随机移除集合里面num个值 默认移除一个
smove [key] [key1] [value] #移动key集合value值到key1中
####################################################################
sdiff [key] [key1] #差集
sinter [key] [key1] #交集
sunion [key] [key1] #并集 返回集合后的结果
####################################################################
127.0.0.1:6379> smembers set
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> smembers set1
1) "3"
2) "4"
3) "5"
127.0.0.1:6379> sdiff set set1 #两个集合的差集
1) "1"
2) "2"
127.0.0.1:6379> sinter set set1 #交集
1) "3"
127.0.0.1:6379> sunion set set1 #并集
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
####################################################################
8.哈希hash
####################################################################
hset [key] [field] [value] #设置一个哈希表,key哈希键,field相当于字段,value相当于字段值
hmset [key] [field] [value] [field1] [value1] #同时设置多个值
hget [key] [field] #获取指定字段值
hmget [key] [field] [field1] #获取多个字段值
hgetall [key] #获取所有字段值
####################################################################
hlen [key] #获取哈希表field长度
hdel [key] [field] [field1] #删除哈希表指定字段,可以同时删除多个字段
hexists [key] [field] #判断哈希指定字段是否存在
hkeys [key] #获取哈希里面的keys
hvals [key] #获取哈希里面的值
hincrby [key] [field] [num] #指定字段递增num,num可以为负数(-1)
hsetnx [key] [field] [value] #不存在则设置,存在则返回0
####################################################################
9.有序zset集合
####################################################################
zadd [key] [weight] [value] #给有序集合添加值,weight权重
zrange [key] 0 -1 #获取集合所有值
zrangebyscore [key] -inf +inf #从小到大排序,-inf代表负无穷,+inf代表正无穷
zrevrange [key] 0 -1 #获取集合数据,从大到小排序
zrangebyscore [key] -inf +inf withscores #获取键跟值,-inf,+inf可以指定区间
zcard [key] #获取集合里面的键个数
zcount [key] [min] [max] #获取指定区间键个数
####################################################################
127.0.0.1:6379> zadd test 1 one #给有序集合添加一个元素
(integer) 1
127.0.0.1:6379> zadd test 2 two
(integer) 1
127.0.0.1:6379> zadd test 3 three
(integer) 1
127.0.0.1:6379> zadd test 4 four
(integer) 1
####################################################################
127.0.0.1:6379> zrange test 0 -1 #获取有序集合所有元素
1) "one"
2) "two"
3) "three"
4) "four"
127.0.0.1:6379> zrangebyscore test -inf +inf #从低到高排序
1) "one"
2) "two"
3) "three"
4) "four"
####################################################################
127.0.0.1:6379> zrevrange test 0 -1 #从高到低排序
1) "four"
2) "three"
3) "two"
4) "one"
####################################################################
127.0.0.1:6379> zrangebyscore test -inf +inf withscores #获取键跟值
1) "one"
2) "1"
3) "two"
4) "2"
5) "three"
6) "3"
7) "four"
8) "4"
####################################################################
127.0.0.1:6379> zrangebyscore test 0 2 withscores #获取0-2之间的值
1) "one"
2) "1"
3) "two"
4) "2"
####################################################################
10.Geospatial地理位置
geoadd [key] [longitude] [dimension] [field] [longitude1] [dimension1] [field1] #设置值
geopos [key] [field] [field1] #获取指定字段值
geodist [key] [field] [field1] [unit] #获取两点之间的距离,unit单位
georadius [key] [longitude] [dimension] [num] [unit] #获取指定经纬度范围内的数据
georadius [key] [longitude] [dimension] [num] [unit] withcoord #获取指定经纬度范围内的数据并显示其定位信息
georadius [key] [longitude] [dimension] [num] [unit] withdist #获取指定经纬度范围内的数据并显示其距离,unit(单位m/km等)
georadius [key] [longitude] [dimension] [num] [unit] withdist count [n] #获取指定经纬度范围内的n条数据
georadiusbymember [key] [field] [num] [unit] #获取指定field字段范围内的数据
geohash [key] [field] [field1] #获取两地距离以字符的方式显示
zrange [key] 0 -1 #获取所有元素
zrem [key] [field] #删除指定元素
####################################################################
127.0.0.1:6379> georadius china 110 30 1000 km
1) "chongqi"
2) "shengzhen"
127.0.0.1:6379> georadius china 110 30 500 km
1) "chongqi"
127.0.0.1:6379>
####################################################################
127.0.0.1:6379> geoadd china 106.50 29.53 chongqi 114.05 22.52 shengzhen
(integer) 2
127.0.0.1:6379> geopos china shengzhen beijing
1) 1) "114.04999762773513794"
2) "22.5200000879503861"
2) 1) "116.39999896287918091"
2) "39.90000009167092543"
127.0.0.1:6379> geodist china beijing shanghai km
"1067.3788"
####################################################################
127.0.0.1:6379> georadius china 110 30 500 km withcoord #获取指定经纬度范围内的数据并显示其定位信息
1) 1) "chongqi"
2) 1) "106.49999767541885376"
2) "29.52999957900659211"
127.0.0.1:6379> georadius china 110 30 500 km withdist #获取指定经纬度范围内的数据并显示其距离
1) 1) "chongqi"
2) "341.9374"
127.0.0.1:6379> georadius china 110 30 500 km withdist count 1 #获取指定经纬度范围内的一条数据
1) 1) "chongqi"
2) "341.9374"
127.0.0.1:6379> georadiusbymember china beijing 1000 km #获取指定字段范围内的数据
1) "beijing"
127.0.0.1:6379> geohash china beijing shengzhen #获取两地距离以字符的方式显示
1) "wx4fbxxfke0"
2) "ws10578st80"
127.0.0.1:6379> zrange china 0 -1 #获取所有元素
1) "chongqi"
2) "shengzhen"
3) "shanghai"
4) "beijing"
127.0.0.1:6379> zrem china beijing #删除指定元素
(integer) 1
####################################################################
11.Hyperloglog
pfadd [key] [value] [value1] #创建一组元素
pfcount [key] #获取数据的基数
pfmerge [key] [key1] [key2] #合并key1,key2到key3
12.Bitmap
只有两种情况的业务就可以用这个统计,例如一周打卡次数
该类型大小只有一个bit,只能存储0,1
setbit [key] [field] [0-1] #设置元素
getbit [key] [field] #获取字段值
bitcount [key] #获取1的总数
bitop [condition] [new-key] [key] [key1...] #1:条件 2:新key 3-n:需统计的key;统计数放到新的key
13.Redis事务
Redis事务本质:一组命令的集合,一个事务中的所有命令都会被序列化,在事务执行过程中,会按照顺序执行。
特性:一次性、顺序性、排他性
Redis事务没有隔离级别的概念
所有的命令在事务中,并没有直接被执行,只有发起执行命令的时候才会被执行
Redis单条命令保证原子性,但是事务不保证原子性
Redis的事务:
-
开启事务(multi)
-
命令入队(......)
-
执行事务(exec)
####################################################################
127.0.0.1:6379> multi #开启事务
OK
127.0.0.1:6379> set a 1 #命令入队
QUEUED
127.0.0.1:6379> set b 2
QUEUED
127.0.0.1:6379> get a
QUEUED
127.0.0.1:6379> exec #执行事务
1) OK
2) OK
3) "1"
####################################################################
127.0.0.1:6379> multi #开启事务
OK
127.0.0.1:6379> set c 1 #命令入队
QUEUED
127.0.0.1:6379> set d 2
QUEUED
127.0.0.1:6379> get c
QUEUED
127.0.0.1:6379> discard #放弃事务
OK
127.0.0.1:6379> get d
(nil)
####################################################################
127.0.0.1:6379> multi #开启事务
OK
127.0.0.1:6379> set name zhangsan
QUEUED
127.0.0.1:6379> incr name #运行时异常事务可以继续执行
QUEUED
127.0.0.1:6379> set e 5
QUEUED
127.0.0.1:6379> get name
QUEUED
127.0.0.1:6379> exec #执行事务
1) OK
2) (error) ERR value is not an integer or out of range
3) OK
4) "zhangsan"
####################################################################
127.0.0.1:6379> multi
OK
127.0.0.1:6379> getall age #编译异常,代码错误事务则不会执行
(error) ERR unknown command `getall`, with args beginning with: `age`,
127.0.0.1:6379> set name wangwu
QUEUED
127.0.0.1:6379> set a 1
QUEUED
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
####################################################################
14.Redis锁
Redis里面的watch相当于乐观锁
-
乐观锁:认为所有事务都不会发生错误,只有在更新的时候做判断
-
悲观锁:认为任何事务都会发生错误,每个事务都加上锁,效率低
####################################################################
# 加锁后,正常运行事务
127.0.0.1:6379> set money 100 #设置money值
OK
127.0.0.1:6379> set out 0 #设置out值
OK
127.0.0.1:6379> watch money #监控money
OK
127.0.0.1:6379> multi #打开事务
OK
127.0.0.1:6379> decrby money 10 #命令操作
QUEUED
127.0.0.1:6379> incrby money 10 #命令操作
QUEUED
127.0.0.1:6379> exec #执行事务
1) (integer) 90
2) (integer) 100
####################################################################
# 多线程修改数据
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby money 10
QUEUED
127.0.0.1:6379> incrby out 10
QUEUED
#此时另一线程修改同一键值
127.0.0.1:6379> exec
(nil) #事务运行失败
####################################################################
127.0.0.1:6379> get money
"100"
127.0.0.1:6379> get out
"0"
127.0.0.1:6379> incrby money 100
(integer) 200
127.0.0.1:6379> incrby out 100
(integer) 100
127.0.0.1:6379> get money
"200"
127.0.0.1:6379> get out
"100"
####################################################################
127.0.0.1:6379> unwatch #若运行失败,先运行unwatch解锁
OK
127.0.0.1:6379> watch money #重新监控
OK
127.0.0.1:6379> multi #重新添加事务
OK
127.0.0.1:6379> decrby out 50 #命令操作
QUEUED
127.0.0.1:6379> incrby money 50 #命令操作
QUEUED
127.0.0.1:6379> exec #执行事务
1) (integer) 50
2) (integer) 250
####################################################################
15.Redis配置文件
1.单位
2.包含文件
3.网络配置
4.通用GENERAL
5.持久化
持久化,在规定时间内,执行了多少次操作,则会持久化到文件.rdb/.aof
Redis是内存数据库,如果没有持久化,那么数据断电及失
6.aof配置
16.RDB(Redis database)
在指定时间间隔内将内存中的额数据集快照写入磁盘,恢复就是直接将快照中的文件直接读写到内存
Redis会单独创建(fork)一个子进程进行持久化,会先将数据写入到一个临时文件中,待持久化过程快结束,再用临时文件替换上次持久化好的文件,整个过程,主进程是不进行任何IO操作,确保了极高的性能,如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加高效,RDB的缺点是最后一次持久化的数据可能丢失。一般情况下不需要修改RDB默认配置。
rdb默认保存的文件是dump.rdb
1.恢复rdb文件
-
只需要将rdb文件放在Redis启动目录,Redis启动会自动检查dump.rdb恢复其数据
-
查看redis启动目录
127.0.0.1:6379> config get dir
1) "dir"
2) "/usr/local/bin"
2.优点
-
适合大规模的数据恢复
-
对数据的完整性要求不高
3.缺点
-
需要一定的时间间隔进程操作,如果Redis意外宕机了,最后一次修改数据就没有了
-
fork进程的时候,会占用一定的内存空间
17.AOF
优点:
-
每一次修改都同步,文件的完整性会更好
-
每秒同步一次,可能会丢失一秒的数据
-
从不同步,效率更高
缺点:
-
相对于数据文件来说,aof远程大于rdb,修复的速度也比rdb慢
-
aof运行效率比rdb慢,默认配置rdb持久化
18.订阅
# 实时接收
127.0.0.1:6379> subscribe [channel] #订阅频道
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "wechat"
3) (integer) 1
1) "message"
2) "wechat"
3) "message"
127.0.0.1:6379> publish [channel] [message] #发送消息到某个频道
(integer) 1
19.主从复制
只需配置从库,不用配置主库
info replication #查看当前库的信息
# Replication
role:master #角色 master主机
connected_slaves:0 #0台从机
复制3个配置文件,修改对应的配置
1、端口号
2、pid文件名
3、log文件
4、dump.rdb文件
修改完毕之后,打开3个连接,启动3个Redis服务器,通过进程信息可以查看
ps -ef|grep redis #查看系统进程
slaveof 127.0.0.1 6379 #添加主机
slaveof no one #如果上头没有主结点,自己就变成主结点,如果这时候主结点回来,他依旧是主结点,得重新配置
修改配置文件的主从复制(如果主机有密码把密码配置上)
主从复制相关特性:
-
主机可以写,从机不能写只能读取主机相关数据
-
主机断开连接,从机依旧可以连接到主机,但是没有写操作,这个时候主机如果回来依旧可以写入数据
-
命令行配置的主从,如果重启,从库又会变成主库
-
只要变回从机,主机的数据就会马上同步(全量复制)
-
每个Redis服务器可以有多个从库,但只有一个主库
20.哨兵模式
# 进入哨兵配置文件
vim sentinel.conf
sentinel monitor [name] 127.0.0.1 6379 1 #哨兵监控的服务器(主机) 后面1代表主机挂了从机自动投票,票数最多的成为主机
sentinel.serve sentinel.conf