一、redis-benchmark redis自带的压力测试工具!
如果按照默认路径安装,该工具安装在路径/usr/local/bin目录下
可选参数说明:
序号 | 选项 | 描述 | 默认值 |
---|---|---|---|
1 | -h | 指定服务器主机名 | 127.0.0.1 |
2 | -p | 指定服务器端口 | 6379 |
3 | -s | 指定服务器socket | |
4 | -c | 指定并发连接数 | 50 |
5 | -n | 指定请求数 | 10000 |
6 | -d | 以字节的形式指定 SET/GET 值的数据大小 | 2 |
7 | -k | 1=keep alive ;0=reconnect | 1 |
8 | -r | SET/GET/INCR 使用随机 key, SADD 使用随机值 | |
9 | -P | 通过管道传输 请求 | 1 |
10 | -q | 强制退出 redis。仅显示 query/sec 值 | |
11 | --csv | 以 CSV 格式输出 | |
12 | -l | 生成循环,永久执行测试 | |
13 | -t | 仅运行以逗号分隔的测试命令列表 | |
14 | -I | Idle 模式。仅打开 N 个 idle 连接并等待。 |
下面来测试下100个并发连接数,100000个请求
命令:redis-benchmark -h localhost -p 6379 -c 100 -n 100000
部分结果及说明如下:
[root@VM_0_2_centos bin]# redis-benchmark -h localhost -p 6379 -c 100 -n 100000
====== PING_INLINE ======
100000 requests completed in 1.86 seconds # 100000个请求在1.86秒内请求完毕
100 parallel clients # 每次请求有100个并发客户端
3 bytes payload # 每次写入 3 个字节的数据
keep alive: 1 # 保持一个连接,一台服务器来处理这些请求的
host configuration "save": 900 1 300 10 60 10000 # 当前快照触发条件配置,表示900秒(15分钟)内有1个更改,300秒(5分钟)内有10个更改以及60秒内有10000个更改。满足任何一个就会触发RDB备份
host configuration "appendonly": no # 未开启aof持久化
multi-thread: no #未开启多线程模式
0.00% <= 0.6 milliseconds
0.01% <= 0.7 milliseconds
3.88% <= 0.8 milliseconds
12.60% <= 0.9 milliseconds
22.23% <= 1.0 milliseconds
32.01% <= 1.1 milliseconds
41.79% <= 1.2 milliseconds
51.48% <= 1.3 milliseconds
61.08% <= 1.4 milliseconds
70.63% <= 1.5 milliseconds
80.23% <= 1.6 milliseconds
89.56% <= 1.7 milliseconds
94.38% <= 1.8 milliseconds
96.58% <= 1.9 milliseconds
97.68% <= 2 milliseconds
99.37% <= 3 milliseconds
99.64% <= 5 milliseconds
99.67% <= 6 milliseconds
99.80% <= 7 milliseconds
99.83% <= 8 milliseconds
99.90% <= 9 milliseconds
99.96% <= 10 milliseconds
100.00% <= 10 milliseconds # 所有的请求在10豪秒内完成
53792.36 requests per second # 每秒处理的请求次数 53792.36 次
二、Redis的库操作
redis默认有16个数据库,类似数组,下标从0开始,每个数据库相对独立,默认是0号数据库,我们可以在redis.conf配置中看到如下相关配置
下面是对Redis的库操作命令演示
localhost:6379> set name along # 在默认数据库中设置值
OK
localhost:6379> get name
"along"
localhost:6379> select 2 # 切换到2号数据库
OK
localhost:6379[2]> get name # 2号数据库中没有数据,说明每个数据库都是相对独立的
(nil)
localhost:6379[2]> select 0 # 切换回0号数据库
OK
localhost:6379> dbsize # 查看当前数据库中总的数据总数
(integer) 1
localhost:6379> keys * # 查看当前所有的key(生产环境谨慎使用)
1) "name"
localhost:6379> flushdb # 清空当前数据库(生产环境不要使用)
OK
localhost:6379> keys *
(empty array)
localhost:6379> flushall # 清空所有数据库(生产环境不要使用)
OK
三、Redis的键操作
keys:查看数据库中已存在的key,支持正则表达式查找
语法:keys pattern
localhost:6379> keys * # 查看所有的key(生产环境慎用)
1) "China:city:1"
2) "USA:city:1"
3) "China:city:3"
4) "China:city:2"
5) "USA:city:2"
localhost:6379> keys China* # 查找以China开头的key
1) "China:city:1"
2) "China:city:3"
3) "China:city:2"
localhost:6379> keys USA* # 查看以USA开头的key
1) "USA:city:1"
2) "USA:city:2"
exists:判断一个或多个key是否存在,会返回存在的key的数量
语法:exists key [key ...]
localhost:6379> exists name
(integer) 1
localhost:6379> exists name name2
(integer) 2
localhost:6379> exists name name3
(integer) 1
move:将当前库的一个key移动到另一个库
语法:move key db
localhost:6379> move China:city:1 1 # 将名为China:city:1的key移动到1号数据库
(integer) 1
localhost:6379> get China:city:1 # 当前数据库中没有这个key了
(nil)
expire:为已存在的key设置过期时间
语法:expire key seconds
localhost:6379> set name along
OK
localhost:6379> get name
"along"
localhost:6379> expire name 5 # 设置值为name的key的过期时间为5秒
(integer) 1
localhost:6379> ttl name # 查看name的状态
(integer) 4
localhost:6379>
localhost:6379> ttl name
(integer) 2
localhost:6379> ttl name
(integer) 1
localhost:6379> ttl name
(integer) -2 # 负数表示已过期
localhost:6379> get name
(nil)
set 的可选参数
set 语法:set key value [EX seconds|PX milliseconds] [NX|XX] [KEEPTTL]
EX seconds|PX milliseconds:设置值的同时设置过期时间
localhost:6379> set name along ex 10 # 设置key的同时设置过期时间为10s
localhost:6379> set name along px 10000 # 设置key的同时设置过期时间为10000ms
NX:只有在key不存在时才创建
localhost:6379> set name along nx
OK
localhost:6379> get name
"along"
localhost:6379> set name yue nx
(nil)
localhost:6379> get name
"along"
XX:只有在key存在时才创建,会覆盖
localhost:6379> del name
(integer) 1
localhost:6379> set name along xx # key不存在,创建失败
(nil)
localhost:6379> get name
(nil)
localhost:6379> set name along
OK
localhost:6379> get name
"along"
localhost:6379> set name yue xx # key存在,覆盖
OK
localhost:6379> get name
"yue"
KEEPTTL:Redis6.x版本加入的新参数,官方给的解释是(Retain the time to live associated with the key)保留生存时间与密钥关联,以后讨论
del:删除一个或多个键
语法:del key [key ...]
localhost:6379> set name along
OK
localhost:6379> get name
"along"
localhost:6379> del name
(integer) 1
localhost:6379> get name
(nil)
四、Redis的五大基本数据类型
Redis的五大基本数据类型有:string(字符串)、hashes(哈希)、lists(链表)、sets(不重复集合)、sorted sets(有序集合)
1. String(字符串,单值单vlaue)
Redis中的基本类型,一个key对应一个String类型的value,value的长度最大不能超过512M
和java中的String类有很多方法,同样的Redis也为String提供了很多方法
append:对key的内容进行追加,如果key不存在就等同于set
语法:append key value
localhost:6379> set speak hello
OK
localhost:6379> get speak
"hello"
localhost:6379> append speak " world"
(integer) 11
localhost:6379> get speak
"hello world"
strlen: 获取长度
语法:strlen key
localhost:6379> strlen speek
(integer) 11
incr/decr 和 incrby/decrby:递增和递减
语法:
incr/decr key
incrby/decrby key increment
localhost:6379> set count 0
OK
localhost:6379> incr count # +1
(integer) 1
localhost:6379> get count
"1"
localhost:6379> decr count # -1
(integer) 0
localhost:6379> get count
"0"
localhost:6379> incrby count 3 # +3
(integer) 3
localhost:6379> get count
"3"
localhost:6379> decrby count 2 # -2
(integer) 1
localhost:6379> get count
"1"
getrange/setrange:获取/设置指定范围的字符串
语法:
getrange key start end
setrange key offset value
从指定位置开始替换字符串
localhost:6379> set range abcdefg
OK
localhost:6379> getrange range 0 -1 # 获取全部
"abcdefg"
localhost:6379> getrange range 1 3 # 获取下标为1到3的字符串
"bcd"
localhost:6379> setrange range 1 XXX # 从下标为1的字符串开始替换,替换内容为XXX
(integer) 7
localhost:6379> get range
"aXXXefg"
setex:设置值得同时设置过期时间
语法:setex key seconds value
localhost:6379> setex name 5 along # key为name value为along 过期时间为为5秒
OK
setnx:如果不存在才设置值,等同于上文提到的 set key value nx
语法:setnx key value
localhost:6379> del name
(integer) 0
localhost:6379> setnx name along
(integer) 1
localhost:6379> setnx name yue
(integer) 0
localhost:6379> get name
"along"
mset / mget / msetnx:批量设置
语法:
mset key value [key value ...]
mget key [key ...]
msetnx key value [key value ...]
localhost:6379> mset key1 value1 key2 value2 key3 value3
OK
localhost:6379> keys key*
1) "key3"
2) "key1"
3) "key2"
localhost:6379> mget key1 key2
1) "value1"
2) "value2"
localhost:6379> msetnx key4 value4 key5 value5
(integer) 1
localhost:6379> keys key*
1) "key5"
2) "key3"
3) "key1"
4) "key2"
5) "key4"
localhost:6379> msetnx key3 value4 key6 value6 # msetnx是一个原子性操作,要么全部成功,要么全部失败
(integer) 0
getset:先get返回旧的值,然后再set新值
语法:getset key value
localhost:6379> get name
"along"
localhost:6379> getset name yue
"along"
localhost:6379> get name
"yue"
2. Hashes(哈希)
可以理解为以字符串作为key,hashMap作为value的数据结构,十分适合用来存储对象
下面是对其增增删改查到操作示例,其命令都是以h
开头
hset/hget:最基础的设置值和查看值
语法:
hset key field value [field value ...]
hget key field
localhost:6379> hset myhash name1 along # 设置单个值,返回成功个数
(integer) 1
localhost:6379> hset myhash name1 yue # 返回0,说明值相同不会覆盖
(integer) 0
localhost:6379> hset myhash name2 ming name3 wang # 一次追加设置多个值,返回成功个数
(integer) 2
localhost:6379> hget myhash name1 # 查看myhash中name1的值
"yue"
hmset:hset的增强版本,field相同时可以覆value
语法:hmset key field value [field value ...]
localhost:6379> hmset myhash name1 yueyue
OK
localhost:6379> hget myhash name1
"yueyue" # 原来的yue被改成了yueyue
hgetall:查看一个key的所有内容
``语法:hgetall key`
localhost:6379> hgetall myhash
1) "name1"
2) "yueyue"
3) "name2"
4) "ming"
5) "name3"
6) "wang"
7) "name4"
8) "si"
hlen:获取key的field数量
语法:
localhost:6379> hlen myhash
(integer) 4
hkeys:查看所有一个key下所有的field
语法:hkeys key
localhost:6379> hkeys myhash
1) "name1"
2) "name2"
3) "name3"
4) "name4"
hincrby:为一个key下的field的value增加指定的值(和String的incrby同理)
语法:hincrby key field increment
localhost:6379> hset myhash count 3
(integer) 1
localhost:6379> hincrby myhash count 4 # +4
(integer) 7
localhost:6379> hincrby myhash count -5 # -5
(integer) 2
localhost:6379> hincrby myhash name1 3
(error) ERR hash value is not an integer # 只对数字有效
hsetnx:和String的setnx同理,只有不存在时才创建
语法:hsetnx key field value
localhost:6379> hsetnx myhash name1 lisi # name1已存在,创建失败
(integer) 0
localhost:6379> hsetnx myhash name5 lisi # 创建成功
(integer) 1
hdel:删除key的一个或多个field,当所有的field都被删掉时,key也就消失了
语法:hdel key field [field ...]
localhost:6379> hgetall myhash
1) "name1"
2) "yueyue"
3) "name2"
4) "ming"
5) "name3"
6) "wang"
7) "name4"
8) "si"
9) "count"
10) "2"
11) "name5"
12) "lisi"
localhost:6379> hdel myhash name5 name4 # 删除指定的field
(integer) 2
localhost:6379> hgetall myhash
1) "name1"
2) "yueyue"
3) "name2"
4) "ming"
5) "name3"
6) "wang"
7) "count"
8) "2"
localhost:6379> del myhash # 如果要整个删除,直接用del干掉整个key
(integer) 1
localhost:6379> hgetall myhash
(empty array)
3. List(链表)
直接将其理解为java中的List,key是对象名,value就是链表内容。
lpush/rpush:从左或从右像列表中添加元素
语法:
lpush/rpush key element [element ...]
localhost:6379> lpush list along yue wang
(integer) 3
localhost:6379> rpush list xixi
(integer) 4
lrange:查看指定下标范围内的值
语法:lrange key start stop
localhost:6379> lrange list 0 -1 # 查看全部
1) "wang"
2) "yue"
3) "along"
4) "xixi"
localhost:6379> lrange list 0 2
1) "wang"
2) "yue"
3) "along"
lindex:获取指定下标的元素(0表示第一个,-1表示最后一个),相当于list.get(index)
语法:lindex key index
localhost:6379> lrange list 0 -1
1) "si"
2) "li"
3) "yue"
4) "along"
localhost:6379> lindex list 1
"li"
localhost:6379> lindex list 0
"si"
localhost:6379> lindex list -1
"along"
lpop/rpop:从数组左边/右边弹出一个元素,相当于list.getFirst()和list.getLast(),不同的是redis中去完后会移除元素
语法:lpop/rpop key
localhost:6379> lrange list 0 -1
1) "wang"
2) "yue"
3) "along"
4) "xixi"
localhost:6379> lpop list
"wang"
localhost:6379> rpop list
"xixi"
localhost:6379> lrange list 0 -1
1) "yue"
2) "along"
lrem:删除列表中指定的元素,指定删除个数
语法:lrem key count element
localhost:6379> lrange list 0 -1
1) "li"
2) "li"
3) "li"
4) "li"
5) "li"
6) "li"
7) "yue"
8) "along"
localhost:6379> lrem list 3 li
(integer) 3
localhost:6379> lrange list 0 -1
1) "li"
2) "li"
3) "li"
4) "yue"
5) "along"
llen:返回列表的长度,相当于list.size()
语法:llen key
localhost:6379> llen list
(integer) 5
ltrim:对一个列表进行修剪,返回指定的区间元素
语法:ltrim key start stop
localhost:6379> lrange list 0 -1
1) "li"
2) "li"
3) "li"
4) "yue"
5) "along"
localhost:6379> ltrim list 2 4
OK
localhost:6379> lrange list 0 -1
1) "li"
2) "yue"
3) "along"
rpoplpush:将一个列表中的最后一个元素弹出,放入到新的列表的最左边
语法:rpoplpush source destination
source是原来的列表,destination是新的列表
localhost:6379> rpoplpush list list2
"along"
localhost:6379> lrange list2 0 -1
1) "along"
lset:修改列表中指定下标的值
语法:lset key index element
localhost:6379> lrange list 0 -1
1) "li"
2) "yue"
localhost:6379> lset list 0 along
OK
localhost:6379> lrange list 0 -1
1) "along"
2) "yue"
localhost:6379> lset list 2 along
(error) ERR index out of range # 超出下标报错
linsert:在指定元素的前后插入数据
语法:linsert key before|after pivot element
localhost:6379> lrange list 0 -1 # 这里特意放了两个相同的元素along
1) "along"
2) "yue"
3) "along"
localhost:6379> linsert list before along XXX
(integer) 4
localhost:6379> lrange list 0 -1 # 可以看出会找到第一个元素进行插入
1) "XXX"
2) "along"
3) "yue"
4) "along"
localhost:6379> linsert list after along XXX
(integer) 5
localhost:6379> lrange list 0 -1
1) "XXX"
2) "along"
3) "XXX"
4) "yue"
5) "along"
总结:
list可以实现的功能很多,既可以用来实现消息队列,也可以用来实现栈
支持从两端插入数据,效率很高,但是不推荐在中间插入数据,效率很低
4. sets(不重复的集合)
直接将其理解为java中的set,不重复集合
sadd:向集合中添加一个或多个元素,重复不会报错,只会存储不重复的元素
语法:sadd key member [member ...]
localhost:6379> sadd set a b c a
(integer) 3
smembers:查看set集合的元素
语法:smembers key
localhost:6379> smembers set
1) "c"
2) "b"
3) "a"
sismember:判断set中是否存在某个值
语法:sismember key member
localhost:6379> sismember set a
(integer) 1
srem:删除成员
语法:srem key member [member ...]
localhost:6379> srem set b
(integer) 1
scard:获取集合的成员个数
语法:scard key
localhost:6379> scard set
(integer) 3
srandmember:随机从set集合中获取一个或多个成员(默认一个)
语法:srandmember key [count]
localhost:6379> srandmember set
"c"
localhost:6379> srandmember set 2
1) "a"
2) "b"
smove:将制定成员从一个set移动到另一个set
语法:smove source destination menber
localhost:6379> smove set set2 a
(integer) 1
localhost:6379> smembers set
1) "c"
2) "b"
localhost:6379> smembers set2
1) "a"
sdiff / sinter / sunion:多个集合的差集、交际、并集
语法:sdiff/sinter/sunion key [key ...]
localhost:6379> sdiff set set2
1) "c"
2) "b"
localhost:6379> sinter set set2
(empty array)
localhost:6379> sunion set set2
1) "c"
2) "a"
3) "b"
5. sorted sets(有序集合)
及zset,在set的基础上增加一个score值,用来给各个成员打分排序
其命令都是以z
开头
zadd: 添加成员
语法zadd key [NX|XX] [CH] [INCR] score member [score member ...]
可选参数解读:
XX: 仅仅更新存在的成员,不添加新成员。
NX: 不更新存在的成员。只添加新成员。
CH: 修改返回值为发生变化的成员总数,原始是返回新添加成员的总数 (CH 是 changed 的意思)。更改的元素是新添加的成员,已经存在的成员更新分数。 所以在命令中指定的成员有相同的分数将不被计算在内。注:在通常情况下,ZADD返回值只计算新添加成员的数量。
INCR: 当ZADD指定这个选项时,成员的操作就等同ZINCRBY命令,对成员的分数进行递增操作。
localhost:6379> zadd students 100 along 99 yue 70 zhansan
(integer) 3
zrange:查看成员
语法:zrange key start stop [withscores]
localhost:6379> zrange students 0 -1 # 查看所有成员
1) "zhansan"
2) "yue"
3) "along"
localhost:6379> zrange students 0 -1 withscores # 查看所有成员,带分数
1) "zhansan"
2) "70"
3) "yue"
4) "99"
5) "along"
6) "100"
zrevrange/zrangebyscore 排序
语法:
zrevrange key start stop [withscores]
zrangebyscore key min max [withscores] [limit offset count]
localhost:6379> zrevrange students 0 -1 withscores # 递减排序
1) "along"
2) "100"
3) "yue"
4) "99"
5) "zhansan"
6) "70"
localhost:6379> zrangebyscore students -inf +inf withscores # 递增排序
1) "zhansan"
2) "70"
3) "yue"
4) "99"
5) "along"
6) "100"
localhost:6379> zrangebyscore students -inf 90 withscores # 小于90分的,递增排序
1) "zhansan"
2) "70"
zrem:移除元素
语法:zrem key member [member ...]
localhost:6379> zrevrange students 0 -1
1) "along"
2) "yue"
3) "zhansan"
localhost:6379> zrem students zhansan
(integer) 1
localhost:6379> zrevrange students 0 -1
1) "along"
2) "yue"
zcard/zcount:统计成员数量
语法:
zcard key
zcount key min max
指定分数区间内的成员个数
localhost:6379> zcard students
(integer) 2
localhost:6379> zcount students 0 100
(integer) 2
localhost:6379> zcount students 0 99
(integer) 1