一、redis性能测试
redis-benchmark 是一个压力测试工具,是官方自带的性能测试工具。
redis-benchmark 命令参数
redis 性能测试工具可选参数如下所示:
序号 | 选项 | 描述 | 默认值 |
---|---|---|---|
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 | 通过管道传输 <numreq> 请求 | 1 |
10 | -q | 强制退出 redis。仅显示 query/sec 值 | |
11 | --csv | 以 CSV 格式输出 | |
12 | -l | 生成循环,永久执行测试 | |
13 | -t | 仅运行以逗号分隔的测试命令列表。 | |
14 | -I | Idle 模式。仅打开 N 个 idle 连接并等待。 |
简单执行一下测试:
测试:100个并发连接,10000个请求
执行命令:redis-benchmark -h localhost -p 6379 -c 100 -n 100000
进入redis默认安装目录 /usr/local/bin 中启动redis
[root@localhost bin]# redis-benchmark -h localhost -p 6379 -c 100 -n 100000
====== PING_INLINE ======
100000 requests completed in 1.14 seconds
100 parallel clients
3 bytes payload
keep alive: 1
81.94% <= 1 milliseconds
99.50% <= 2 milliseconds
99.99% <= 3 milliseconds
100.00% <= 3 milliseconds
87719.30 requests per second
====== PING_BULK ======
100000 requests completed in 1.18 seconds
100 parallel clients
3 bytes payload
keep alive: 1
77.48% <= 1 milliseconds
99.53% <= 2 milliseconds
99.89% <= 3 milliseconds
99.97% <= 4 milliseconds
100.00% <= 4 milliseconds
84961.77 requests per second
====== SET ======
100000 requests completed in 1.16 seconds
100 parallel clients
3 bytes payload
keep alive: 1
79.92% <= 1 milliseconds
99.44% <= 2 milliseconds
99.90% <= 3 milliseconds
99.90% <= 12 milliseconds
100.00% <= 13 milliseconds
100.00% <= 13 milliseconds
86058.52 requests per second
====== GET ======
100000 requests completed in 1.12 seconds
100 parallel clients
3 bytes payload
keep alive: 1
83.42% <= 1 milliseconds
99.84% <= 2 milliseconds
100.00% <= 2 milliseconds
89605.73 requests per second
====== INCR ======
100000 requests completed in 1.13 seconds
100 parallel clients
3 bytes payload
keep alive: 1
82.80% <= 1 milliseconds
99.65% <= 2 milliseconds
100.00% <= 2 milliseconds
88731.15 requests per second
====== LPUSH ======
100000 requests completed in 1.16 seconds
100 parallel clients
3 bytes payload
keep alive: 1
78.40% <= 1 milliseconds
99.63% <= 2 milliseconds
100.00% <= 2 milliseconds
86355.79 requests per second
====== RPUSH ======
100000 requests completed in 1.16 seconds
100 parallel clients
3 bytes payload
keep alive: 1
79.61% <= 1 milliseconds
99.50% <= 2 milliseconds
99.92% <= 15 milliseconds
99.99% <= 16 milliseconds
100.00% <= 16 milliseconds
85910.65 requests per second
====== LPOP ======
100000 requests completed in 1.16 seconds
100 parallel clients
3 bytes payload
keep alive: 1
78.22% <= 1 milliseconds
99.67% <= 2 milliseconds
100.00% <= 2 milliseconds
86430.43 requests per second
====== RPOP ======
100000 requests completed in 1.14 seconds
100 parallel clients
3 bytes payload
keep alive: 1
80.66% <= 1 milliseconds
99.53% <= 2 milliseconds
99.93% <= 3 milliseconds
100.00% <= 3 milliseconds
87336.24 requests per second
====== SADD ======
100000 requests completed in 1.10 seconds
100 parallel clients
3 bytes payload
keep alive: 1
85.11% <= 1 milliseconds
99.82% <= 2 milliseconds
100.00% <= 2 milliseconds
90661.83 requests per second
====== HSET ======
100000 requests completed in 1.17 seconds
100 parallel clients
3 bytes payload
keep alive: 1
77.08% <= 1 milliseconds
99.59% <= 2 milliseconds
100.00% <= 3 milliseconds
100.00% <= 3 milliseconds
85397.09 requests per second
====== SPOP ======
100000 requests completed in 1.17 seconds
100 parallel clients
3 bytes payload
keep alive: 1
79.06% <= 1 milliseconds
99.20% <= 2 milliseconds
99.93% <= 3 milliseconds
100.00% <= 3 milliseconds
85616.44 requests per second
====== LPUSH (needed to benchmark LRANGE) ======
100000 requests completed in 1.20 seconds
100 parallel clients
3 bytes payload
keep alive: 1
74.79% <= 1 milliseconds
99.38% <= 2 milliseconds
99.89% <= 3 milliseconds
99.96% <= 4 milliseconds
100.00% <= 4 milliseconds
83472.46 requests per second
====== LRANGE_100 (first 100 elements) ======
100000 requests completed in 3.36 seconds
100 parallel clients
3 bytes payload
keep alive: 1
0.00% <= 1 milliseconds
24.02% <= 2 milliseconds
80.28% <= 3 milliseconds
95.57% <= 4 milliseconds
99.37% <= 5 milliseconds
99.86% <= 6 milliseconds
99.96% <= 7 milliseconds
99.99% <= 8 milliseconds
100.00% <= 8 milliseconds
29788.50 requests per second
^CANGE_300 (first 300 elements): 12106.58
[root@localhost bin]# redis-benchmark -h localhost -p 6379 -c 100 -n 100000
====== PING_INLINE ======
100000 requests completed in 1.13 seconds
100 parallel clients
3 bytes payload
keep alive: 1
82.57% <= 1 milliseconds
99.87% <= 2 milliseconds
100.00% <= 3 milliseconds
100.00% <= 3 milliseconds
88731.15 requests per second
====== PING_BULK ======
100000 requests completed in 1.11 seconds
100 parallel clients
3 bytes payload
keep alive: 1
84.39% <= 1 milliseconds
99.72% <= 2 milliseconds
99.97% <= 3 milliseconds
100.00% <= 3 milliseconds
89928.05 requests per second
====== SET ======
100000 requests completed in 1.16 seconds
100 parallel clients
3 bytes payload
keep alive: 1
79.64% <= 1 milliseconds
99.63% <= 2 milliseconds
100.00% <= 2 milliseconds
86430.43 requests per second
====== GET ======
100000 requests completed in 1.12 seconds
100 parallel clients
3 bytes payload
keep alive: 1
84.03% <= 1 milliseconds
99.63% <= 2 milliseconds
99.89% <= 3 milliseconds
100.00% <= 3 milliseconds
89285.71 requests per second
====== INCR ======
100000 requests completed in 1.14 seconds
100 parallel clients
3 bytes payload
keep alive: 1
81.28% <= 1 milliseconds
99.74% <= 2 milliseconds
100.00% <= 3 milliseconds
100.00% <= 3 milliseconds
87719.30 requests per second
====== LPUSH ======
100000 requests completed in 1.26 seconds
100 parallel clients
3 bytes payload
keep alive: 1
70.63% <= 1 milliseconds
98.37% <= 2 milliseconds
99.41% <= 3 milliseconds
99.68% <= 4 milliseconds
99.70% <= 5 milliseconds
99.72% <= 6 milliseconds
99.76% <= 7 milliseconds
99.80% <= 10 milliseconds
99.84% <= 11 milliseconds
100.00% <= 11 milliseconds
79239.30 requests per second
====== RPUSH ======
100000 requests completed in 1.17 seconds
100 parallel clients
3 bytes payload
keep alive: 1
77.07% <= 1 milliseconds
99.80% <= 2 milliseconds
100.00% <= 2 milliseconds
85543.20 requests per second
====== LPOP ======
100000 requests completed in 1.20 seconds
100 parallel clients
3 bytes payload
keep alive: 1
73.55% <= 1 milliseconds
99.66% <= 2 milliseconds
100.00% <= 2 milliseconds
83542.19 requests per second
====== RPOP ======
100000 requests completed in 1.16 seconds
100 parallel clients
3 bytes payload
keep alive: 1
78.35% <= 1 milliseconds
99.76% <= 2 milliseconds
99.97% <= 3 milliseconds
100.00% <= 3 milliseconds
86281.27 requests per second
====== SADD ======
100000 requests completed in 1.13 seconds
100 parallel clients
3 bytes payload
keep alive: 1
81.52% <= 1 milliseconds
99.89% <= 2 milliseconds
100.00% <= 2 milliseconds
88105.73 requests per second
====== HSET ======
100000 requests completed in 1.15 seconds
100 parallel clients
3 bytes payload
keep alive: 1
78.64% <= 1 milliseconds
99.87% <= 2 milliseconds
100.00% <= 2 milliseconds
86805.56 requests per second
====== SPOP ======
100000 requests completed in 1.14 seconds
100 parallel clients
3 bytes payload
keep alive: 1
81.76% <= 1 milliseconds
99.61% <= 2 milliseconds
99.90% <= 10 milliseconds
99.99% <= 11 milliseconds
100.00% <= 11 milliseconds
87412.59 requests per second
====== LPUSH (needed to benchmark LRANGE) ======
100000 requests completed in 1.18 seconds
100 parallel clients
3 bytes payload
keep alive: 1
76.46% <= 1 milliseconds
99.43% <= 2 milliseconds
99.91% <= 3 milliseconds
100.00% <= 4 milliseconds
100.00% <= 4 milliseconds
84817.64 requests per second
====== LRANGE_100 (first 100 elements) ======
100000 requests completed in 3.38 seconds
100 parallel clients
3 bytes payload
keep alive: 1
0.00% <= 1 milliseconds
23.43% <= 2 milliseconds
80.89% <= 3 milliseconds
96.01% <= 4 milliseconds
99.55% <= 5 milliseconds
99.77% <= 6 milliseconds
99.80% <= 7 milliseconds
99.81% <= 10 milliseconds
99.85% <= 11 milliseconds
99.91% <= 12 milliseconds
99.96% <= 19 milliseconds
100.00% <= 20 milliseconds
100.00% <= 20 milliseconds
29629.63 requests per second
====== LRANGE_300 (first 300 elements) ======
100000 requests completed in 8.34 seconds
100 parallel clients
3 bytes payload
keep alive: 1
0.00% <= 2 milliseconds
0.02% <= 3 milliseconds
6.31% <= 4 milliseconds
25.89% <= 5 milliseconds
48.11% <= 6 milliseconds
71.67% <= 7 milliseconds
88.69% <= 8 milliseconds
94.52% <= 9 milliseconds
97.91% <= 10 milliseconds
99.65% <= 11 milliseconds
99.99% <= 12 milliseconds
100.00% <= 12 milliseconds
11988.97 requests per second
====== LRANGE_500 (first 450 elements) ======
100000 requests completed in 11.96 seconds
100 parallel clients
3 bytes payload
keep alive: 1
0.00% <= 4 milliseconds
0.23% <= 5 milliseconds
9.05% <= 6 milliseconds
22.72% <= 7 milliseconds
37.67% <= 8 milliseconds
53.92% <= 9 milliseconds
70.55% <= 10 milliseconds
84.58% <= 11 milliseconds
90.99% <= 12 milliseconds
94.95% <= 13 milliseconds
97.38% <= 14 milliseconds
98.85% <= 15 milliseconds
99.58% <= 16 milliseconds
99.76% <= 17 milliseconds
99.87% <= 18 milliseconds
99.93% <= 19 milliseconds
99.97% <= 20 milliseconds
100.00% <= 21 milliseconds
100.00% <= 21 milliseconds
8360.50 requests per second
====== LRANGE_600 (first 600 elements) ======
100000 requests completed in 15.49 seconds
100 parallel clients
3 bytes payload
keep alive: 1
0.00% <= 3 milliseconds
0.00% <= 4 milliseconds
0.03% <= 5 milliseconds
0.10% <= 6 milliseconds
2.27% <= 7 milliseconds
11.41% <= 8 milliseconds
22.08% <= 9 milliseconds
33.61% <= 10 milliseconds
46.01% <= 11 milliseconds
58.87% <= 12 milliseconds
71.66% <= 13 milliseconds
83.39% <= 14 milliseconds
89.39% <= 15 milliseconds
93.06% <= 16 milliseconds
95.57% <= 17 milliseconds
97.17% <= 18 milliseconds
98.20% <= 19 milliseconds
98.84% <= 20 milliseconds
99.16% <= 21 milliseconds
99.31% <= 22 milliseconds
99.43% <= 23 milliseconds
99.53% <= 24 milliseconds
99.63% <= 25 milliseconds
99.73% <= 26 milliseconds
99.81% <= 27 milliseconds
99.90% <= 28 milliseconds
99.97% <= 29 milliseconds
99.99% <= 30 milliseconds
100.00% <= 30 milliseconds
6457.45 requests per second
====== MSET (10 keys) ======
100000 requests completed in 1.42 seconds
100 parallel clients
3 bytes payload
keep alive: 1
40.75% <= 1 milliseconds
98.82% <= 2 milliseconds
99.95% <= 3 milliseconds
100.00% <= 3 milliseconds
70274.07 requests per second
分析测试结果:
二、基础使用命令详解
1、redis默认有16个数据库
默认使用的是第0个数据库
2、基础常用命令
切换数据库,命令:select 3
查看数据库大小,命令:dbsize
127.0.0.1:6379> select 3 # 切换数据库
OK
127.0.0.1:6379[3]> dbsize # 查看数据库大小
(integer) 0
127.0.0.1:6379[3]>
数据库中放值,命令:set name helloworld
数据库中取值,命令:get name
查看数据库中所有的key,命令:keys *
127.0.0.1:6379[3]> set name helloworld # 数据库中放值
OK
127.0.0.1:6379[3]> get name # 数据库中取值
"helloworld"
127.0.0.1:6379[3]> keys * # 查看数据库中所有的key
1) "name"
127.0.0.1:6379[3]>
清空当前数据库,命令:flushdb
127.0.0.1:6379[3]> flushdb # 清空当前数据库
OK
127.0.0.1:6379[3]> keys *
(empty list or set)
127.0.0.1:6379[3]>
清空所有数据库,命令:flushall
127.0.0.1:6379[3]> select 3
OK
127.0.0.1:6379[3]> keys *
(empty list or set)
127.0.0.1:6379[3]> set name helloworld
OK
127.0.0.1:6379[3]> keys *
1) "name"
127.0.0.1:6379[3]> select 4
OK
127.0.0.1:6379[4]> keys *
(empty list or set)
127.0.0.1:6379[4]> set name love
OK
127.0.0.1:6379[4]> keys *
1) "name"
127.0.0.1:6379[4]> flushall # 清空所有数据库
OK
127.0.0.1:6379[4]> keys *
(empty list or set)
127.0.0.1:6379[4]> select 3
OK
127.0.0.1:6379[3]> keys *
(empty list or set)
127.0.0.1:6379[3]>
3、redis的端口号
6379 (为什么redis的端口号是6379 Redis端口为什么是6379?_corleone_4ever的博客-CSDN博客_redis端口)
4、redis是单线程的
redis很快,官方表示,redis是基于内存操作的,CPU不是redis的性能瓶颈,redis的性能瓶颈是根据机器的内存和网络带宽来决定的。
redis为什么单线程还这么快?
误区1:高性能的服务器一定是多线程的吗?答案是不一定
误区2:多线程(多线程使用CPU调度会频繁的进行上下文切换,消耗资源)一定比单线程效率高吗?答案是不一定
核心:redis是将所有的数据全部放在内存中的,所有说使用单线程去操作时效率就是最高的,多线程(CPU上下文会切换,耗时的操作),对于内存系统来说,如果没有上下文切换效率就是最高的,多次读写都是在一个CPU上的时候,在内存操作情况下,效率就是最快的。
三、redis基本数据类型
redis英文官方网站:https://redis.io/
redis中文官方网站: Redis中文网
摘自官网说明:
Redis-Key
#########################################################################################
127.0.0.1:6379> keys * # 查看当前数据库中所有的key
(empty list or set)
127.0.0.1:6379> set name hao # 放置一个key值
OK
127.0.0.1:6379> set age 30
OK
127.0.0.1:6379> keys *
1) "age"
2) "name"
127.0.0.1:6379> exists name # 判断当前key是否存在
(integer) 1
127.0.0.1:6379> exists name1
(integer) 0
127.0.0.1:6379> get name # 获取一个key值
"hao"
127.0.0.1:6379> get age
"30"
127.0.0.1:6379> move age 1 # 移除当前的key
(integer) 0
127.0.0.1:6379> move age 2
(integer) 1
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> set age 30
OK
127.0.0.1:6379> keys *
1) "age"
2) "name"
127.0.0.1:6379> expire name 10 # 设置key的过期时间,单位是秒
(integer) 1
127.0.0.1:6379> ttl name # 查看当前key的过期剩余时间还有多少秒
(integer) 7
127.0.0.1:6379> ttl name
(integer) 3
127.0.0.1:6379> ttl name
(integer) 1
127.0.0.1:6379> set name hao
127.0.0.1:6379> type name # 查看当前key的数据类型
string
127.0.0.1:6379> type age
string
127.0.0.1:6379>
1、String字符串类型
#########################################################################################
127.0.0.1:6379> keys * # 查看当前数据库所有的key值
(empty list or set)
127.0.0.1:6379> set name hao # 放值
OK
127.0.0.1:6379> get name # 获取值
"hao"
127.0.0.1:6379> exists name # 判断key是否存在
(integer) 1
127.0.0.1:6379> append name "hello" # 追加字符串,如果当前key不存在,就相当于set key
(integer) 8
127.0.0.1:6379> get name
"haohello"
127.0.0.1:6379> strlen name # 获取字符串的长度
(integer) 8
#########################################################################################
/**
* 字符串中i++或者i--操作
*/
127.0.0.1:6379> set views 0
OK
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> incr views # 自增1
(integer) 1
127.0.0.1:6379> incr views
(integer) 2
127.0.0.1:6379> get views
"2"
127.0.0.1:6379> decr views # 自减1
(integer) 1
127.0.0.1:6379> decr views
(integer) 0
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> incrby views 10 # 设置步长,指定增量
(integer) 10
127.0.0.1:6379> incrby views 10
(integer) 20
127.0.0.1:6379> get views
"20"
127.0.0.1:6379> decrby views 5 # 设置步长,指定减量
(integer) 15
127.0.0.1:6379> decrby views 5
(integer) 10
127.0.0.1:6379> get views
"10"
#########################################################################################
/**
* 字符串范围range
*/
127.0.0.1:6379> set name "hello,i love china" # 设置name的值
OK
127.0.0.1:6379> get name
"hello,i love china"
127.0.0.1:6379> getrange name 0 3 # 获取字符串[0,3]
"hell"
127.0.0.1:6379> getrange name 0 -1 # 获取全部的字符串,和get key是一样的
"hello,i love china"
#########################################################################################
/**
* 替换字符串
*/
127.0.0.1:6379> set key2 abcdefg
OK
127.0.0.1:6379> get key2
"abcdefg"
127.0.0.1:6379> setrange key2 1 xx # 替换指定位置开始的字符串
(integer) 7
127.0.0.1:6379> get key2
"axxdefg"
#########################################################################################
/**
* setex (set with expire) # 设置过期时间
* setnx (set if not expire) # 如果不存在设置过期时间,一般在分布式锁中会常用
*/
127.0.0.1:6379> setex key1 30 "hello" # 设置key1的值为hello,30秒后过期
OK
127.0.0.1:6379> ttl key1
(integer) 23
127.0.0.1:6379> get key1
"hello"
127.0.0.1:6379> ttl key1
(integer) 10
127.0.0.1:6379> setnx mykey "redis" # 如果mykey不存在,则创建mykey并设置值为redis
(integer) 1
127.0.0.1:6379> keys *
1) "mykey"
127.0.0.1:6379> setnx mykey "MongoDB" # 如果mykey存在,则会创建失败
(integer) 0
127.0.0.1:6379> get mykey
"redis"
#########################################################################################
/**
* mset 批量设置多个值
* mget 批量获取多个值
*/
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 # 同时设置多个值
OK
127.0.0.1:6379> keys *
1) "k1"
2) "k2"
3) "k3"
127.0.0.1:6379> mget k1 k2 k3 # 同时获取多个值
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> msetnx k1 v2 k4 v4 # msetnx是一个原子性的操作(要么全部成功,要么全部失败)
(integer) 0
127.0.0.1:6379> get k4
(nil)
/**
* 设置对象 set user:1{name:zhangsan,age:20} 设置一个user:1对象值为json字符串来保存一个对象
* key的设计规则:user:{id}:{field}
*/
127.0.0.1:6379> mset user:1:name zhangsan user:1:age 20
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "zhangsan"
2) "20"
#########################################################################################
/**
* getset 先get在set
*/
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> getset db redis # 如果不存在值,则返回nil
(nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db mongodb # 如果存在值,则获取原来的值,并设置新的值
"redis"
127.0.0.1:6379> get db
"mongodb"
2、List数据类型
在redis里面,我们可以把list看成是堆、栈、阻塞队列
所有的list命令都是用 l 开头的
#########################################################################################
/**
* lpush key value 将一个值或者多个值,插入到列表的头部(左)
* lrange key start stop 通过区间获取值
* rpush key value 将一个值或者多个值,插入到列表的尾部(右)
*/
127.0.0.1:6379> lpush list one # 将一个值或者多个值,插入到列表的头部(左)
(integer) 1
127.0.0.1:6379> lpush list two
(integer) 2
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> lrange list 0 -1 # 获取list中所有的值
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> lrange list 0 1 # 通过区间获取值
1) "three"
2) "two"
127.0.0.1:6379> rpush list rightone # 将一个值或者多个值,插入到列表的尾部(右)
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
4) "rightone"
#########################################################################################
/**
* lpop key 移除list中的第一个元素
* rpop key 移除list中的最后一个元素
*/
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
4) "rightone"
127.0.0.1:6379> lpop list # 移除list中的第一个元素
"three"
127.0.0.1:6379> rpop list # 移除list中的最后一个元素
"rightone"
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
#########################################################################################
/**
* lindex key index 通过下标获取list中的某一个值
*/
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
127.0.0.1:6379> lindex list 1 # 通过下标获取list中的某一个值
"one"
127.0.0.1:6379> lindex list 0
"two"
#########################################################################################
/**
* llen key 获取list列表的长度
*/
127.0.0.1:6379> lpush list one
(integer) 1
127.0.0.1:6379> lpush list two
(integer) 2
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> llen list # 获取列表的长度
(integer) 3
#########################################################################################
/**
* lrem key count value 移除list中值
*/
127.0.0.1:6379> lpush list three
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "three"
3) "two"
4) "one"
127.0.0.1:6379> lrem list 1 one
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "three"
3) "two"
127.0.0.1:6379> lrem list 1 three # 移除list集合中指定个数的value,精确匹配
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "three"
3) "two"
127.0.0.1:6379> lrem list 2 three
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1) "two"
#########################################################################################
/**
* ltrim key start stop 通过下标截取list指定的长度,这个list已经被改变了,只剩下截取的元素
*/
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> rpush mylist "hello"
(integer) 1
127.0.0.1:6379> rpush mylist "hello1"
(integer) 2
127.0.0.1:6379> rpush mylist "hello2"
(integer) 3
127.0.0.1:6379> rpush mylist "hello3"
(integer) 4
127.0.0.1:6379> ltrim mylist 1 2 # 通过下标截取list指定的长度,这个list已经被改变了,只剩下截取的元素
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "hello1"
2) "hello2"
#########################################################################################
/**
* rpoplpush 移除列表中的最后一个元素,将它移动到新的列表中
*/
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> rpush mylist "hello"
(integer) 1
127.0.0.1:6379> rpush mylist "hello1"
(integer) 2
127.0.0.1:6379> rpush mylist "hello2"
(integer) 3
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "hello1"
3) "hello2"
127.0.0.1:6379> rpoplpush mylist myotherlist # 移除mylist列表中的最后一个元素,将它移动到新的列表myotherlist中
"hello2"
127.0.0.1:6379> lrange mylist 0 -1 # 查看原来的mylist列表
1) "hello"
2) "hello1"
127.0.0.1:6379> lrange myotherlist 0 -1 # 查看目标列表myotherlist中,确实存在移动过去的值
1) "hello2"
#########################################################################################
/**
* lset
*/
127.0.0.1:6379> exists list # 判断这个列表是否存在
(integer) 0
127.0.0.1:6379> lset list 0 item # 如果不存在这个列表,我们去更新就会报错
(error) ERR no such key
127.0.0.1:6379> lpush list value1
(integer) 1
127.0.0.1:6379> lrange list 0 0
1) "value1"
127.0.0.1:6379> lset list 0 item # 如果存在这个列表,那么就会更新当前下标的值
OK
127.0.0.1:6379> lrange list 0 0
1) "item"
127.0.0.1:6379> lset list 1 other # 如果不存在,则会报错
(error) ERR index out of range
#########################################################################################
/**
* linsert 将某个具体的value值插入到列表中某个元素的前面或者后面
*/
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> rpush mylist "hello"
(integer) 1
127.0.0.1:6379> rpush mylist "world"
(integer) 2
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "world"
127.0.0.1:6379> linsert mylist before "world" "other" # 将other元素插入到mylist列表中world元素的前面(before)
(integer) 3
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "other"
3) "world"
127.0.0.1:6379> linsert mylist after "world" "laugh" # 将laugh元素插入到mylist列表中world元素的后面(after)
(integer) 4
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "other"
3) "world"
4) "laugh"
redis中list数据类型总结:
- 它实际上是一个链表,before node after,left,right都可以插入值。
- 如果key不存在,就会创建新的链表。
- 如果key存在,就会新增内容。
- 如果移除了所以值,就是空链表,也就代表不存在了。
- 在两边插入或者改动值,效率最高,如果在中间元素插入或者改动值的话,相对来说效率会低一点。
3、Set(集合)数据类型
set集合中的元素是不能重复的。
所有的set命令都是用 s 开头的。
#########################################################################################
/**
* sadd set集合中添加一个元素
* smembers set 查看指定set集合中所有的元素
* sismember set 判断某一个值是否在set集合中
*/
127.0.0.1:6379> sadd myset "hello" # set集合中添加一个元素
(integer) 1
127.0.0.1:6379> sadd myset "world"
(integer) 1
127.0.0.1:6379> smembers myset # 查看指定set集合中所有的元素
1) "hello"
2) "world"
127.0.0.1:6379> sismember myset "hello" # 判断某一个值是否在set集合中
(integer) 1
127.0.0.1:6379> sismember myset "china"
(integer) 0
#########################################################################################
/**
* scard 获取set集合中的内容元素个数
*/
127.0.0.1:6379> sadd myset "hello"
(integer) 1
127.0.0.1:6379> sadd myset "world"
(integer) 1
127.0.0.1:6379> smembers myset
1) "hello"
2) "world"
127.0.0.1:6379> scard myset # 获取set集合中的内容元素个数
(integer) 2
#########################################################################################
/**
* srem 移除set集合中的指定元素
*/
127.0.0.1:6379> sadd myset "hello"
(integer) 1
127.0.0.1:6379> sadd myset "world"
(integer) 1
127.0.0.1:6379> sadd myset "china"
(integer) 1
127.0.0.1:6379> smembers myset
1) "hello"
2) "china"
3) "world"
127.0.0.1:6379> srem myset "hello" # 移除set集合中的指定元素
(integer) 1
127.0.0.1:6379> smembers myset
1) "china"
2) "world"
#########################################################################################
/**
* set集合是无序不重复,抽随机
* srandmember myset 随机抽取set集合中的一个元素
* srandmember myset count 随机抽取set集合中指定个数的元素
*/
127.0.0.1:6379> sadd myset "hello"
(integer) 1
127.0.0.1:6379> sadd myset "world"
(integer) 1
127.0.0.1:6379> sadd myset "appel"
(integer) 1
127.0.0.1:6379> sadd myset "china"
(integer) 1
127.0.0.1:6379> sadd myset "banana"
(integer) 1
127.0.0.1:6379> smembers myset
1) "hello"
2) "appel"
3) "china"
4) "world"
5) "banana"
127.0.0.1:6379> srandmember myset # 随机抽取set集合中的一个元素
"world"
127.0.0.1:6379> srandmember myset
"appel"
127.0.0.1:6379> srandmember myset
"banana"
127.0.0.1:6379> srandmember myset 2 # 随机抽取set集合中指定个数的元素
1) "world"
2) "banana"
127.0.0.1:6379> srandmember myset 1
1) "world"
#########################################################################################
/**
* spop myset 随机删除set集合中的一个元素
* spop myset 1 随机删除set集合中指定个数的元素
*
*/
127.0.0.1:6379> sadd myset "a"
(integer) 1
127.0.0.1:6379> sadd myset "b"
(integer) 1
127.0.0.1:6379> sadd myset "c"
(integer) 1
127.0.0.1:6379> smembers myset
1) "a"
2) "c"
3) "b"
127.0.0.1:6379> spop myset # 随机删除set集合中的一个元素
"a"
127.0.0.1:6379> spop myset 1 # 随机删除set集合中指定个数的元素
1) "c"
127.0.0.1:6379> smembers myset
1) "b"
#########################################################################################
/**
* smove 将set集合中的指定的一个值,移动到另外一个set集合中
*
*
*/
127.0.0.1:6379> sadd myset "a"
(integer) 1
127.0.0.1:6379> sadd myset "b"
(integer) 1
127.0.0.1:6379> sadd myset "c"
(integer) 1
127.0.0.1:6379> sadd myset1 "a1"
(integer) 1
127.0.0.1:6379> sadd myset1 "b1"
(integer) 1
127.0.0.1:6379> smembers myset
1) "a"
2) "c"
3) "b"
127.0.0.1:6379> smembers myset1
1) "a1"
2) "b1"
127.0.0.1:6379> smove myset myset1 "a" # 将set集合中的指定的一个值,移动到另外一个set集合中
(integer) 1
127.0.0.1:6379> smembers myset
1) "c"
2) "b"
127.0.0.1:6379> smembers myset1
1) "a"
2) "a1"
3) "b1"
#########################################################################################
/**
* 数字集合类型
* sdiff 差集
* sinter 交集
* sunion 并集
*/
127.0.0.1:6379> sadd myset1 "a"
(integer) 1
127.0.0.1:6379> sadd myset1 "b"
(integer) 1
127.0.0.1:6379> sadd myset1 "c"
(integer) 1
127.0.0.1:6379> sadd myset2 "c"
(integer) 1
127.0.0.1:6379> sadd myset2 "d"
(integer) 1
127.0.0.1:6379> sadd myset2 "e"
(integer) 1
127.0.0.1:6379> smembers myset1
1) "a"
2) "c"
3) "b"
127.0.0.1:6379> smembers myset2
1) "d"
2) "e"
3) "c"
127.0.0.1:6379> sdiff myset1 myset2 # 获取两个set集合的差集
1) "a"
2) "b"
127.0.0.1:6379> sinter myset1 myset2 # 获取两个set集合的交集
1) "c"
127.0.0.1:6379> sunion myset1 myset2 # 获取两个set集合的并集
1) "d"
2) "b"
3) "c"
4) "e"
5) "a"
4、Hash(哈希)数据类型
Map集合,key-map的时候这个值是一个map集合。
所有的hash命令都是用 h 开头的。
#########################################################################################
/**
* hset set一个具体的key-value值
* hget 获取hash中的指定字段的值
* hmset set多个key-value值
* hmget 获取hash中多个字段值
* hgetall 获取hash中全部的数据,是以key-value形式展示
* hdel 删除hash指定key字段的值,删除之后对应的value值也就没有了
*/
127.0.0.1:6379> hset myhash field "a" # set一个具体的key-value值
(integer) 1
127.0.0.1:6379> hget myhash field # 获取hash中的指定字段的值
"a"
127.0.0.1:6379> hmset myhash field1 "hello" field2 "world" # set多个key-value值
OK
127.0.0.1:6379> hmget myhash field field1 field2 # 获取hash中多个字段值
1) "a"
2) "hello"
3) "world"
127.0.0.1:6379> hgetall myhash # 获取hash中全部的数据,是以key-value形式展示
1) "field"
2) "a"
3) "field1"
4) "hello"
5) "field2"
6) "world"
127.0.0.1:6379> hdel myhash field # 删除hash指定key字段的值,删除之后对应的value值也就没有了
(integer) 1
127.0.0.1:6379> hgetall myhash
1) "field1"
2) "hello"
3) "field2"
4) "world"
#########################################################################################
/**
* hlen 获取hash表中的字段数量
*
*/
127.0.0.1:6379> hmset myhash field1 "hello" field2 "world"
OK
127.0.0.1:6379> hgetall myhash
1) "field1"
2) "hello"
3) "field2"
4) "world"
127.0.0.1:6379> hlen myhash # 获取hash表中的字段数量
(integer) 2
#########################################################################################
/**
* hexists 判断hash中指定字段是否存在
*/
127.0.0.1:6379> hset myhash field1 "hello" field2 "world"
(integer) 2
127.0.0.1:6379> hgetall myhash
1) "field1"
2) "hello"
3) "field2"
4) "world"
127.0.0.1:6379> hexists myhash field1 # 判断hash中指定字段是否存在
(integer) 1
127.0.0.1:6379> hexists myhash field3
(integer) 0
#########################################################################################
/**
* hkeys 只获取hash中所有的key
* hvals 只获取hash中所有的value
*/
127.0.0.1:6379> hset myhash field1 "hello" field2 "world"
(integer) 2
127.0.0.1:6379> hgetall myhash
1) "field1"
2) "hello"
3) "field2"
4) "world"
127.0.0.1:6379> hkeys myhash # 只获取hash中所有的key
1) "field1"
2) "field2"
127.0.0.1:6379> hvals myhash # 只获取hash中所有的value
1) "hello"
2) "world"
#########################################################################################
/**
* hincrby 指定增量
*
*/
127.0.0.1:6379> hset myhash field1 5
(integer) 1
127.0.0.1:6379> hincrby myhash field1 1 # 指定增量
(integer) 6
127.0.0.1:6379> hincrby myhash field1 -1
(integer) 5
127.0.0.1:6379> hsetnx myhash field2 "hello" # 如果不存在,则可以设置
(integer) 1
127.0.0.1:6379> hsetnx myhash field2 "world" # 如果存在,则不可以设置
(integer) 0
5、Zset(有序集合)数据类型
在set基础上,增加了一个值 set k1 v1 zset k1 score1 v1
#########################################################################################
/**
* zadd 添加一个值或多个值
* zrange 查看所有的值
*/
127.0.0.1:6379> zadd myset 1 one # 添加一个值
(integer) 1
127.0.0.1:6379> zadd myset 2 two 3 three # 添加多个值
(integer) 2
127.0.0.1:6379> zrange myset 0 -1 # 查看所有的值
1) "one"
2) "two"
3) "three"
#########################################################################################
/**
* 排序如何实现
* zrangebyscore
*/
127.0.0.1:6379> zadd salary 2500 zhangsan # 添加三个用户及对应的薪水
(integer) 1
127.0.0.1:6379> zadd salary 5000 lisi
(integer) 1
127.0.0.1:6379> zadd salary 500 zhaohao
(integer) 1
127.0.0.1:6379> zrangebyscore salary -inf +inf # 显示全部用户的用户,从小到大升序排列
1) "zhaohao"
2) "zhangsan"
3) "lisi"
127.0.0.1:6379> zrangebyscore salary -inf +inf withscores # 显示全部用户的用户并附带显示成绩,从小到大升序排列
1) "zhaohao"
2) "500"
3) "zhangsan"
4) "2500"
5) "lisi"
6) "5000"
127.0.0.1:6379> zrangebyscore salary -inf 2500 withscores # 显示工资小于2500的用户并附带显示成绩,从小到大升序排列
1) "zhaohao"
2) "500"
3) "zhangsan"
4) "2500"
#########################################################################################
/**
* zrem 移除set集合中指定的元素
* zcard 获取有序集合中的个数
*/
127.0.0.1:6379> zadd salary 2500 zhangsan
(integer) 1
127.0.0.1:6379> zadd salary 5000 lisi
(integer) 1
127.0.0.1:6379> zadd salary 500 zhaohao
(integer) 1
127.0.0.1:6379> zrangebyscore salary -inf +inf
1) "zhaohao"
2) "zhangsan"
3) "lisi"
127.0.0.1:6379> zrem salary lisi # 移除set集合中指定的元素
(integer) 1
127.0.0.1:6379> zrange salary 0 -1
1) "zhaohao"
2) "zhangsan"
127.0.0.1:6379> zcard salary # 获取有序集合中的个数
(integer) 2