(1)全称:Remote Dictionary Server(远程字典服务器)。是完全开源免费的,用C语言编写
的, 遵守BSD协议。是一个高性能的(key/value)分布式内存数据库,基于内存运行并支持持久化的NoSQL数据库,是当前最热门的NoSql数据库之一,也被人们称为数据结构服务器。
(2)Redis 与其他 key - value 缓存产品有以下三个特点
i)Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用 ii)Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结
构的存储 iii)Redis支持数据的备份,即master-slave模式的数据备份
(1)内存存储和持久化:redis支持异步将内存中的数据写到硬盘上,同时不影响继续服务
(2)取最新N个数据的操作,如:可以将最新的10条评论的ID放在Redis的List集合里面
(3)模拟类似于HttpSession这种需要设定过期时间的功能
(4)发布、订阅消息系统
(5)定时器、计数器
(1)Http://redis.io/
(2)Http://www.redis.cn/
(1)数据类型、基本操作和配置
(2)持久化和复制,RDB/AOF
(3)事务的控制
(4)复制
目前全球最大的 Redis 用户是新浪微博,在新浪有 200 多台物理机,400 多个端口正在运行着 Redis,有+4G 的数据跑在 Redis 上来为微博用户提供服务。
在新浪微博 Redis 的部署场景很多,大概分为如下的 2 种:
第一种是应用程序直接访问 Redis 数据库
第二种是应用程序直接访问 Redis,只有当 Redis 访问失败时才访问 MySQL!
Redis与其他数据库和软件的对比
一些数据库和缓存服务器的特性与功能
名称 | 类型 | 数据存储选项 | 附加功能 |
Redis | 使用内存存储(in-memory)的非关系数据库 | 字符串、列表、集合、散列表、有序集合 | 发布与订阅,主从复制 (master/slavereplication),持久化,脚本(存储过程,storedprocedure) |
memcached | 使用内存存储的键值缓存 | 键值之间的映射 | 为提升性能而设的多线程服务器 |
MySQL | 关系数据库 | 每个数据库可以包含多个表,每个表可以包含多个行;可以处理多个表的视图(view);支持空间(spatial)和第三方扩展 | 支持ACID性质(需要使用 InnoDB),主从复制和主主复制(master/master replication) |
PostgreSQL | 关系数据库 | 每个数据库可以包含多个表,每个表可以 包含多个行;可以处理多个表的视图;支持空间和第三方扩展;支持可定制类型 |
支持ACID性质,主从复制,由第三方支持的多主复制(multi-masterreplication) |
MongoDB | 使用硬盘存储(on-disk)的非关系文档存储 | 每个数据库可以包含多个表,每个表可以 包含多个无schema(schema- less)的BSON文档 |
支持map-reduce操作,主从复制,分片,空间索(spatial index) |
基于CentOS 7.9 x86-64 系统安装
配置epel的yum源
[root@localhost ~]# yum install
http://mirrors.163.com/centos/7.3.1611/extras/x86_64/Packages/epel-release-7-
9.noarch.rpm
在线yum安装
[root@localhost ~]# yum install redis #安装完毕目前是redis-3.2.3-1.el7.x86_64.rpm
安装最新版本使用remi:
[root@localhost ~]# yum install ftp://rpmfind.net/linux/remi/enterprise/7/remi/x86_64/redis-
4.0.1-1.el7.remi.x86_64.rpm
启动服务:
[root@localhost ~]# systemctl start redis
[root@localhost ~]# systemctl enable redis
验证测试:
[root@localhost ~]# netstat -lnupt | grep :6379
tcp 0 0 127.0.0.1:6379 0.0.0.0:*
LISTEN 11413/redis-server
[root@localhost ~]# ps -ef | grep redis
redis 11413 1 0 10:46 ? 00:00:03 /usr/bin/redis-server
127.0.0.1:6379
[root@localhost ~]# lsof -i tcp:6379
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
redis-ser 11413 redis 6u IPv4 29352 0t0 TCP localhost:6379
(LISTEN)
登录:
[root@localhost ~]# redis-cli
127.0.0.1:6379> help
redis-cli 4.0.1
To get help about Redis commands type:
"help @" to get a list of commands in
"help " for help on
"help " to get a list of possible help topics
"quit" to exit
To set redis-cli preferences:
":set hints" enable online hints
":set nohints" disable online hints
Set your preferences in ~/.redisclirc
127.0.0.1:6379> quit
下载:
[root@localhost ~]# curl -O
http://download.redis.io/releases/redis-4.0.1.tar.gz
解压:
[root@localhost ~]# tar xf redis-4.0.1.tar.gz -C /usr/local/src/
安装:
[root@localhost ~]# cd /usr/local/src/redis-4.0.1/
[root@localhost redis-4.0.1]# yum install gcc gcc-c++ make -y
[root@localhost redis-4.0.1]# make
[root@localhost redis-4.0.1]# make install
启动:
[root@localhost redis-4.0.1]# mkdir -p /etc/redis
[root@localhost redis-4.0.1]# cp redis.conf /etc/redis
[root@localhost redis-4.0.1]# cd
[root@localhost ~]# sed -i.bak 's/daemonize no/daemonize yes/'
/etc/redis/redis.conf
[root@localhost ~]# redis-server /etc/redis/redis.conf
5448:C 12 Aug 11:54:21.743 # oO0OoO0OoO0Oo Redis is starting
oO0OoO0OoO0Oo
5448:C 12 Aug 11:54:21.743 # Redis version=4.0.1, bits=64,
commit=00000000, modified=0, pid=5448, just started
5448:C 12 Aug 11:54:21.743 # Configuration loaded
登录:
[root@localhost ~]# redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> quit
发送命令:
redis-cli -h 127.0.0.1 -p 6379
redis-cli PING
redis-cli
命令返回值
状态回复,e.g. >PING
错误恢复, e.g. >ECMD
整数回复, e.g. >INCR foo
字符串回复,e.g. >GET foo >GET notexists`
多行字符串回复,e.g. >KEYS *
源码配置服务脚本:
1.2.3.1 创建用户和组
[root@localhost ~]# groupadd -g 935 -r redis
[root@localhost ~]# useradd -u 935 -g 935 -r -d /var/lib/redis -c “redis server” -s /sbin/nologin redis
[root@localhost ~]# mkdir -p /var/lib/redis
[root@localhost ~]# chown -R redis /var/lib/redis
[root@localhost ~]# chmod -R 700 /var/lib/redis
1.2.3.2 修改配置文件/etc/redis/redis.conf
[root@localhost ~]# vim /etc/redis/redis.conf
dir /var/lib/redis/
daemonize no
1.2.3.3 创建服务脚本
[root@localhost ~]# vim /usr/lib/systemd/system/redis.service
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=/usr/local/bin/redis-server /etc/redis/redis.conf --
daemonize no
ExecStop=/usr/bin/kill -9 `pidof redis-server`
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
[root@localhost ~]# systemctl daemon-reload
1.2.3.4 测试脚本
[root@localhost ~]# systemctl stop redis
[root@localhost ~]# ps -ef | grep redis
root 14888 5517 0 10:36 pts/1 00:00:00 grep --color=auto
redis
[root@localhost ~]# systemctl start redis
[root@localhost ~]# ps -ef | grep redis
redis 14895 1 0 10:37 ? 00:00:00
/usr/local/bin/redis-server 127.0.0.1:6379
windows 下安装:
windows下载安装 :Releases · microsoftarchive/redis · GitHub
安装:
打开cmd命令窗口,使用命令进行安装和注册redis到window服务
安装命令:redis-server.exe --service-install redis.windows.conf --loglevel verbose
启动服务命令:redis-server.exe --service-start
关闭服务命令:redis-server.exe --service-stop
redis已经运行,但要获得好的性能,还需要对配置文件进行合理的配置
1. Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程
daemonize no
2. 当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过
pidfile指定
pidfile /var/run/redis.pid
3. 指定Redis监听端口,默认端口为6379,为什么选用6379作为默认端口,因为6379在手机按键上MERZ对
应的号码,而MERZ取自意大利歌女Alessia Merz的名字
port 6379
4. 绑定的主机地址
bind 127.0.0.1
5. 当客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能
timeout 300
6. 指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为
verbose
loglevel verbose
7. 日志记录方式,默认为标准输出,如果配置Redis为守护进程方式运行,而这里又配置为日志记录方式为
标准输出,则日志将会发送给/dev/null
logfile stdout
8. 设置数据库的数量,默认数据库为0,可以使用SELECT命令在连接上指定数据库id
databases 16
9. 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合
save
Redis默认配置文件中提供了三个条件:
save 900 1
save 300 10
save 60 10000
分别表示900秒(15分钟)内有1个更改,300秒(5分钟)内有10个更改以及60秒内有10000个更改。
10. 指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间,可
以关闭该选项,但会导致数据库文件变的巨大
rdbcompression yes
11. 指定本地数据库文件名,默认值为dump.rdb
dbfilename dump.rdb
12. 指定本地数据库存放目录 dir ./
13. 设置当本机为slav服务时,设置master服务的IP地址及端口,在Redis启动时,它会自动从master进
行数据同步
slaveof
14. 当master服务设置了密码保护时,slav服务连接master的密码
masterauth
15. 设置Redis连接密码,如果配置了连接密码,客户端在连接Redis时需要通过AUTH命令
提供密码,默认关闭
requirepass foobared16. 设置同一时间最大客户端连接数,默认无限制,Redis可以同时打开的客户端连接数为Redis进程可以打
开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis会
关闭新的连接并向客户端返回max number of clients reached错误信息 maxclients 128
17. 指定Redis最大内存限制,Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清
除已到期或即将到期的Key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以
进行读取操作。Redis新的vm机制,会把Key存放内存,Value会存放在swap区
maxmemory
18. 指定是否在每次更新操作后进行日志记录,Redis在默认情况下是异步的把数据写入磁盘,如果不开启,
可能会在断电时导致一段时间内的数据丢失。因为 redis本身同步数据文件是按上面save条件来同步的,所
以有的数据会在一段时间内只存在于内存中。默认为no
appendonly no
19. 指定更新日志文件名,默认为appendonly.aof
appendfilename appendonly.aof
20. 指定更新日志条件,共有3个可选值:
no:表示等操作系统进行数据缓存同步到磁盘(快)
always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全)
everysec:表示每秒同步一次(折衷,默认值)
appendfsync everysec
21. 指定是否启用虚拟内存机制,默认值为no,简单的介绍一下,VM机制将数据分页存放,由Redis将访问
量较少的页即冷数据swap到磁盘上,访问多的页面由磁盘自动换出到内存中(在后面的文章我会仔细分析
Redis的VM机制)
vm-enabled no
22. 虚拟内存文件路径,默认值为/tmp/redis.swap,不可多个Redis实例共享
vm-swap-file /tmp/redis.swap
23. 将所有大于vm-max-memory的数据存入虚拟内存,无论vm-max-memory设置多小,所有索引数据都是内
存存储的(Redis的索引数据 就是keys),也就是说,当vm-max-memory设置为0的时候,其实是所有value
都存在于磁盘。默认值为0 vm-max-memory 0
24. Redis swap文件分成了很多的page,一个对象可以保存在多个page上面,但一个page上不能被多个
对象共享,vm-page-size是要根据存储的 数据大小来设定的,作者建议如果存储很多小对象,page大小最
好设置为32或者64bytes;如果存储很大大对象,则可以使用更大的page,如果不 确定,就使用默认
值 vm-page-size 32
25. 设置swap文件中的page数量,由于页表(一种表示页面空闲或使用的bitmap)是在放在内存中的,,
在磁盘上每8个pages将消耗1byte的内存。 vm-pages 134217728
26. 设置访问swap文件的线程数,最好不要超过机器的核数,如果设置为0,那么所有对swap文件的操作都是
串行的,可能会造成比较长时间的延迟。默认值为4 vm-max-threads 4
27. 设置在向客户端应答时,是否把较小的包合并为一个包发送,默认为开启 glueoutputbuf yes
28. 指定在超过一定的数量或者最大的元素超过某一临界值时,采用一种特殊的哈希算法
hash-max-zipmap-entries 64
hash-max-zipmap-value 512
29. 指定是否激活重置哈希,默认为开启 activerehashing yes
30. 指定包含其它的配置文件,可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例
又拥有自己的特定配置文件 include /path/to/local.conf
字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,这便意味着该类型可以接受任何格式的数据,如JPEG图像数据或Json对象描述信息等。在Redis中字符串类型的Value最多可以容纳的数据长度是512M。
命令原型 | 时间 复杂 度 |
命令描述 | 返回值 |
APPEND key value |
O(1) | 如果该Key已经存在,APPEND命令将参数Value的数据追 加到已存在Value的末尾。如果该Key不存在,APPEND命 令将会创建一个新的Key/Value。 |
追加后 Value的 长度。 |
DECR key | O(1) | 将指定Key的Value原子性的递减1。如果该Key不存在, 其初始值为0,在decr之后其值为-1。如果Value的值不能 转换为整型值,如Hello,该操作将执行失败并返回相应 的错误信息。注意:该操作的取值范围是64位有符号整 型。 |
递减后的 Value 值。 |
INCR key | O(1) | 将指定Key的Value原子性的递增1。如果该Key不存在, 其初始值为0,在incr之后其值为1。如果Value的值不能 转换为整型值,如Hello,该操作将执行失败并返回相应 的错误信息。注意:该操作的取值范围是64位有符号整 型。 |
递增后的 Value 值。 |
DECRBY key decrement |
O(1) | 将指定Key的Value原子性的减少decrement。如果该Key 不存在, 其初始值为0,在decrby之后其值为- decrement。如果Value的值不能转换为整型值,如 Hello,该操作将执行失败并返回相应的错误信 息。注 意:该操作的取值范围是64位有符号整型。 |
减少后的 Value 值。 |
INCRBY key increment |
O(1) | 将指定Key的Value原子性的增加increment。如果该Key 不存在, 其初始值为0,在incrby之后其值为 increment。如果Value的值不能转换为整型值,如 Hello,该操作将执行失败并返回相应的错误信 息。注 意:该操作的取值范围是64位有符号整型。 |
增加后的 Value 值。 |
GET key | O(1) | 获取指定Key的Value。如果与该Key关联的Value不是 string类型,Redis将返回错误信息,因为GET命令只能用 于获取string Value。 |
与该Key 相关的 Value, 如果该 Key不存 在,返回 nil。 |
SET key value |
O(1) | 设定该Key持有指定的字符串Value,如果该Key已经存 在,则覆盖其原有值。 |
总是返 回"OK"。 |
GETSET key value |
O(1) | 原子性的设置该Key为指定的Value,同时返回该Key的原 有值。和GET命令一样,该命令也只能处理string Value, 否则Redis将给出相关的错误信息。 |
返回该 Key的原 有值,如 果该Key 之前并不 存在,则 返回nil。 |
STRLEN key |
O(1) | 返回指定Key的字符值长度,如果Value不是string类型, Redis将执行失败并给出相关的错误信息。 |
返回指定 Key的 Value字 符长度, 如果该 Key不存 在,返回 0。 |
SETEX key seconds value |
O(1) | 原子性完成两个操作,一是设置该Key的值为指定字符 串,同时设置该Key在Redis服务器中的存活时间(秒数)。 该命令主要应用于Redis被当做Cache服务器使用时。 |
|
SETNX key value |
O(1) | 如果指定的Key不存在,则设定该Key持有指定字符串 Value,此时其效果等价于SET命令。相反,如果该Key已 经存在,该命令将不做任何操作并返回。 |
1表示设 置成功, 否则0。 |
SETRANGE key offset value |
O(1) | 替换指定Key的部分字符串值。从offset开始,替换的长度 为该命令第三个参 数value的字符串长度,其中如果 offset的值大于该Key的原有值Value的字符串长度, Redis将会在Value的后面补齐(offset - strlen(value))数量 的0x00,之后再追加新值。如果该键不存在,该命令会将 其原值的长度假设为0,并在其后添补offset个0x00后 再 追加新值。鉴于字符串Value的最大长度为512M,因此 offset的最大值为536870911。最后需要注意的是,如果 该命令在执行时致使指定 Key的原有值长度增加,这将会 导致Redis重新分配足够的内存以容纳替换后的全部字符 串,因此就会带来一定的性能折损。 |
修改后的 字符串 Value长 度。 |
GETRANGE key start end |
O(1) | 如果截取的字符串长度很短,我们可以该命令的时间复杂 度视为O(1),否则就是O(N),这里N表示截取的子字符串 长度。该命令在截取子字符串时,将以闭区间的方式同时 包含start(0表示第一个字符)和end所在的字符,如果end 值超过Value的字符长度,该命令将只是截取从start开始 之后所有的字符数据。 |
子字符串 |
SETBIT key offset value |
O(1) | 设置在指定Offset上BIT的值,该值只能为1或0,在设定 后该命令返回该 Offset上原有的BIT值。如果指定Key不存 在,该命令将创建一个新值,并在指定的Offset上设定参 数中的BIT值。如果Offset大于 Value的字符长度,Redis 将拉长Value值并在指定Offset上设置参数中的BIT值,中 间添加的BIT值为0。最后需要说明的是 Offset值必须大于 0。 |
在指定 Offset上 的BIT原 有值。 |
GETBIT key offset |
O(1) | 返回在指定Offset上BIT的值,0或1。如果Offset超过 string value的长度,该命令将返回0,所以对于空字符串 始终返回0。 |
在指定 Offset上 的BIT 值。 |
MGET key [key ...] |
O(1) | N表示获取Key的数量。返回所有指定Keys的Values,如 果其中某个Key不存在,或者其值不为string类型,该Key 的Value将返回nil |
返回一组 指定Keys 的Values 的列表。 |
MSET key value [key value ...] |
O(N) | N表示指定Key的数量。该命令原子性的完成参数中所有 key/value的设置操作,其具体行为可以看成是多次迭代 执行SET命令。 |
该命令不 会失败, 始终返回 OK。 |
MSETNX key value [key value ...] |
O(N) | N表示指定Key的数量。该命令原子性的完成参数中所有 key/value的设置操作,其具体行为可以看成是多次迭代 执行SETNX命令。然而这里需要明确说明的是,如果在这 一批Keys中有任意一个Key已经存在了,那么该操作将全 部回滚,即所有的修改都不会生效。 |
1表示所 有Keys都 设置成 功,0则 表示没有 任何Key 被修改。 |
/> redis-cli #执行Redis客户端工具。
#判断该键是否存在,存在返回1,否则返回0。
redis 127.0.0.1:6379>exists mykey
(integer) 0
#该键并不存在,因此append命令返回当前Value的长度。
redis 127.0.0.1:6379> append mykey "hello"
(integer) 5
#该键已经存在,因此返回追加后Value的长度。
redis 127.0.0.1:6379>append mykey " world"
(integer) 11
#通过get命令获取该键,以判断append的结果。
redis 127.0.0.1:6379>get mykey
"hello world"
#通过set命令为键设置新值,并覆盖原有值。
redis 127.0.0.1:6379>set mykey "this is a test"
OK
redis 127.0.0.1:6379>get mykey
"this is a test"
#获取指定Key的字符长度,等效于C库中strlen函数。
redis 127.0.0.1:6379>strlen mykey
(integer) 14
#设置Key的值为20
redis 127.0.0.1:6379>set mykey 20
OK
#该Key的值递增1
redis 127.0.0.1:6379>incr mykey
(integer) 21
#该Key的值递减1
redis 127.0.0.1:6379>decr mykey
(integer) 20
#删除已有键。
redis 127.0.0.1:6379>del mykey
(integer) 1
#对空值执行递减操作,其原值被设定为0,递减后的值为-1
redis 127.0.0.1:6379>decr mykey
(integer) -1
redis 127.0.0.1:6379>del mykey
(integer) 1
#对空值执行递增操作,其原值被设定为0,递增后的值为1
redis 127.0.0.1:6379> incr mykey
(integer) 1
#将该键的Value设置为不能转换为整型的普通字符串。
redis 127.0.0.1:6379>set mykey hello
OK
#在该键上再次执行递增操作时,Redis将报告错误信息。
redis 127.0.0.1:6379>incr mykey
(error) ERR value is not an integer or out of range
redis 127.0.0.1:6379>set mykey 10
OK
redis 127.0.0.1:6379>decrby mykey 5
(integer) 5
redis 127.0.0.1:6379>incrby mykey 10
(integer) 15
#将计数器的值原子性的递增1
redis 127.0.0.1:6379>incr mycounter
(integer) 1
#在取计数器原有值的同时,并将其设置为新值,这两个操作原子性的同时完成。
redis 127.0.0.1:6379>getset mycounter 0
"1"
#查看设置后的结果。
redis 127.0.0.1:6379>get mycounter
"0"
#设置指定Key的过期时间为10秒。
redis 127.0.0.1:6379>setex mykey 10 "hello"
OK
#通过ttl命令查看一下指定Key的剩余存活时间(秒数),0表示已经过期,-1表示永不过期。
redis 127.0.0.1:6379>ttl mykey
(integer) 4
#在该键的存活期内我们仍然可以获取到它的Value。
redis 127.0.0.1:6379>get mykey
"hello"
#该ttl命令的返回值显示,该Key已经过期。
redis 127.0.0.1:6379>ttl mykey
(integer) 0
#获取已过期的Key将返回nil。
redis 127.0.0.1:6379>get mykey
(nil)
#删除该键,以便于下面的测试验证。
redis 127.0.0.1:6379>del mykey
(integer) 1
#该键并不存在,因此该命令执行成功。
redis 127.0.0.1:6379>setnx mykey "hello"
(integer) 1
#该键已经存在,因此本次设置没有产生任何效果。
redis 127.0.0.1:6379>setnx mykey "world"
(integer) 0
#从结果可以看出,返回的值仍为第一次设置的值。
redis 127.0.0.1:6379>get mykey
"hello"
#设定初始值。
redis 127.0.0.1:6379>set mykey "hello world"
OK
#从第六个字节开始替换2个字节(dd只有2个字节)
redis 127.0.0.1:6379>setrange mykey 6 dd
(integer) 11
#查看替换后的值。
redis 127.0.0.1:6379>get mykey
"hello ddrld"
#offset已经超过该Key原有值的长度了,该命令将会在末尾补0。
redis 127.0.0.1:6379>setrange mykey 20 dd
(integer) 22
#查看补0后替换的结果。
redis 127.0.0.1:6379>get mykey
"hello ddrld\x00\x00\x00\x00\x00\x00\x00\x00\x00dd"
#删除该Key。
redis 127.0.0.1:6379>del mykey
(integer) 1
#替换空值。
redis 127.0.0.1:6379>setrange mykey 2 dd
(integer) 4
#查看替换空值后的结果。
redis 127.0.0.1:6379>get mykey
"\x00\x00dd"
#设置新值。
redis 127.0.0.1:6379>set mykey "0123456789"
OK
#截取该键的Value,从第一个字节开始,到第二个字节结束。
redis 127.0.0.1:6379>getrange mykey 1 2
"12"
#20已经超过Value的总长度,因此将截取第一个字节后面的所有字节。
redis 127.0.0.1:6379>getrange mykey 1 20
"123456789"
redis 127.0.0.1:6379>del mykey
(integer) 1
#设置从0开始计算的第七位BIT值为1,返回原有BIT值0
redis 127.0.0.1:6379> setbit mykey 7 1
(integer) 0
#获取设置的结果,二进制的0000 0001的十六进制值为0x01
redis 127.0.0.1:6379>get mykey
"\x01"
#设置从0开始计算的第六位BIT值为1,返回原有BIT值0
redis 127.0.0.1:6379>setbit mykey 6 1
(integer) 0
#获取设置的结果,二进制的0000 0011的十六进制值为0x03
redis 127.0.0.1:6379>get mykey
"\x03"
#返回了指定Offset的BIT值。
redis 127.0.0.1:6379>getbit mykey 6
(integer) 1
#Offset已经超出了value的长度,因此返回0。
redis 127.0.0.1:6379>getbit mykey 10
(integer) 0
#批量设置了key1和key2两个键。
redis 127.0.0.1:6379>mset key1 "hello" key2 "world"
OK
#批量获取了key1和key2两个键的值。
redis 127.0.0.1:6379>mget key1 key2
1) "hello"
2) "world"
#批量设置了key3和key4两个键,因为之前他们并不存在,所以该命令执行成功并返回1。
redis 127.0.0.1:6379>msetnx key3 "stephen" key4 "liu"
(integer) 1
redis 127.0.0.1:6379>mget key3 key4
1) "stephen"
2) "liu"
#批量设置了key3和key5两个键,但是key3已经存在,所以该命令执行失败并返回0。
redis 127.0.0.1:6379>msetnx key3 "hello" key5 "world"
(integer) 0
#批量获取key3和key5,由于key5没有设置成功,所以返回nil。
redis 127.0.0.1:6379>mget key3 key5
1) "stephen"
2) (nil)
我们可以将Redis中的Hashes类型看成具有String Key和String Value的map容器。所以该类型非常适合于存储值对象的信息。如Username、Password和Age等。如果Hash中包含很少的字段,那么 该类型的数据也将仅占用很少的磁盘空间。每一个Hash可以存储4294967295个键值对。
命令原型 | 时间复杂度 | 命令描述 | 返回值 |
HSET key field value |
O(1) | 为指定的Key设定Field/Value对,如果Key不存 在,该命令将创建新Key以参数中的Field/Value 对,如果参数中的Field在该Key中已经存在,则用 新值覆盖其原有值。 |
1表示新的Field 被设置了新值, 0表示Field已经 存在,用新值覆 盖原有值。 |
HGET key field |
O(1) | 返回指定Key中指定Field的关联值。 | 返回参数中Field 的关联值,如果 参数中的Key或 Field不存,返回 nil。 |
HEXISTS key field |
O(1) | 判断指定Key中的指定Field是否存在。 | 1表示存在,0表 示参数中的Field 或Key不存在 |
HLEN key | O(1) | 获取该Key所包含的Field的数量。 | 返回Key包含的 Field数量,如果 Key不存在,返 回0。 |
HDEL key field [field ...] |
O(1) | 时间复杂度中的N表示参数中待删除的字段数量。 从指定Key的Hashes Value中删除参数中指定的多 个字段,如果不存在的字段将被忽略。如果Key不 存在,则将其视为空Hashes,并返回0. |
实际删除的Field 数量。 |
HSETNX key field value |
O(1) | 只有当参数中的Key或Field不存在的情况下,为指 定的Key设定Field/Value对,否则该命令不会进行 任何操作 |
1表示新的Field 被设置了新值, 0表示Key或Field 已经存在,该命 令没有进行任何 操作。 |
HINCRBY key field increment |
O(1) | 增加指定Key中指定Field关联的Value的值。如果 Key或Field不存在,该命令将会创建一个新Key或 新Field,并将其关联的Value初始化为0,之后再指 定数字增加的操作。该命令支持的数字是64位有符 号整型,即increment可以负数。 |
返回运算后的 值。 |
HGETALL key |
O(N) | 时间复杂度中的N表示Key包含的Field数量。获取 该键包含的所有Field/Value。其返回格式为一个 Field、一个Value,并以此类推。 |
Field/Value的列 表 |
HKEYS key |
O(N) | 时间复杂度中的N表示Key包含的Field数量。返回 指定Key的所有Fields名。 |
Field的列表 |
HVALS key |
O(N) | 时间复杂度中的N表示Key包含的Field数量。返回 指定Key的所有Values名 |
Value的列表 |
HMGET key field [field ...] |
O(N) | 时间复杂度中的N表示请求的Field数量。获取和参 数中指定Fields关联的一组Values。如果请求的 Field不存在,其值返回nil。如果Key不存在,该命 令将其视为空Hash,因此返回一组nil。 |
返回和请求 Fields关联的一 组Values,其返 回顺序等同于 Fields的请求顺 序。 |
HMSET key field value [field value ...] |
O(N) | 时间复杂度中的N表示被设置的Field数量。逐对依 次设置参数中给出的Field/Value对。如果其中某个 Field已经存在,则用新值覆盖原有值。如果Key不 存在,则创建新Key,同时设定参数中的 Field/Value。 |
#在Shell命令行启动Redis客户端程序
/>redis-cli
#给键值为myhash的键设置字段为field1,值为stephen。
redis 127.0.0.1:6379>hset myhash field1 "stephen"
(integer) 1
#获取键值为myhash,字段为field1的值。
redis 127.0.0.1:6379>hget myhash field1
"stephen"
#myhash键中不存在field2字段,因此返回nil。
redis 127.0.0.1:6379>hget myhash field2
(nil)
#给myhash关联的Hashes值添加一个新的字段field2,其值为liu。
redis 127.0.0.1:6379>hset myhash field2 "liu"
(integer) 1
#获取myhash键的字段数量。
redis 127.0.0.1:6379>hlen myhash
(integer) 2
#判断myhash键中是否存在字段名为field1的字段,由于存在,返回值为1。
redis 127.0.0.1:6379>hexists myhash field1
(integer) 1
#删除myhash键中字段名为field1的字段,删除成功返回1。
redis 127.0.0.1:6379>hdel myhash field1
(integer) 1
#再次删除myhash键中字段名为field1的字段,由于上一条命令已经将其删除,因为没有删除,返回0。
redis 127.0.0.1:6379>hdel myhash field1
(integer) 0
#判断myhash键中是否存在field1字段,由于上一条命令已经将其删除,因为返回0。
redis 127.0.0.1:6379>hexists myhash field1
(integer) 0
#通过hsetnx命令给myhash添加新字段field1,其值为stephen,因为该字段已经被删除,所以该命令添
加成功并返回1。
redis 127.0.0.1:6379>hsetnx myhash field1 stephen
(integer) 1
#由于myhash的field1字段已经通过上一条命令添加成功,因为本条命令不做任何操作后返回0。
redis 127.0.0.1:6379>hsetnx myhash field1 stephen
(integer) 0
#删除该键,便于后面示例的测试。
redis 127.0.0.1:6379>del myhash
(integer) 1
#准备测试数据,该myhash的field字段设定值1。
redis 127.0.0.1:6379>hset myhash field 5
(integer) 1
#给myhash的field字段的值加1,返回加后的结果。
redis 127.0.0.1:6379>hincrby myhash field 1
(integer) 6
#给myhash的field字段的值加-1,返回加后的结果。
redis 127.0.0.1:6379>hincrby myhash field -1
(integer) 5
#给myhash的field字段的值加-10,返回加后的结果。
redis 127.0.0.1:6379>hincrby myhash field -10
(integer) -5
#删除该键,便于后面示例测试。
redis 127.0.0.1:6379>del myhash
(integer) 1
#为该键myhash,一次性设置多个字段,分别是field1 = "hello", field2 = "world"。
redis 127.0.0.1:6379>hmset myhash field1 "hello" field2 "world"
OK
#获取myhash键的多个字段,其中field3并不存在,因为在返回结果中与该字段对应的值为nil。
redis 127.0.0.1:6379>hmget myhash field1 field2 field3
1) "hello"
2) "world"
3) (nil)
#返回myhash键的所有字段及其值,从结果中可以看出,他们是逐对列出的。
redis 127.0.0.1:6379>hgetall myhash
1) "field1"
2) "hello"
3) "field2"
4) "world"
#仅获取myhash键中所有字段的名字。
redis 127.0.0.1:6379>hkeys myhash
1) "field1"
2) "field2"
#仅获取myhash键中所有字段的值。
redis 127.0.0.1:6379> hvals myhash
1) "hello"
2) "world"
在Redis中,List类型是的字符串链表。和数据结构中的普通链表一样,我们可以在其头部(left)和尾部(right)添加新的 元素。在插入时,如果该键并不存在,Redis将为该键创建一个新的链表。与此相反,如果链表中所有的元素均被移除,那么该键也将会被从数据库中删除。 List中可以包含的最大元素数量是4294967295。
从元素插入和删除的效率视角来看,如果我们是在链表的两头插入或删除元素,这将会是非常高效的操作,即使链表中已经存储了百万条记录,该操作也可以在常量 时间内完成。然而需要说明的是,如果元素插入或删除操作是作用于链表中间,那将会是非常低效的。相信对于有良好数据结构基础的开发者而言,这一点并不难理 解。
命令原型 | 时间复 杂度 |
命令描述 | 返回值 |
LPUSH key value [value ...] |
O(1) | 在指定Key所关联的List Value的头部插入参数中给 出的所有Values。如果该Key不存在,该命令将在插 入之前创建一个与该Key关联的空链表,之后再将数 据从链表的头部插入。如果该键的Value不是链表类 型,该命令将返回相关的错误信息。 |
插入后 链表中 元素的 数量。 |
LPUSHX key value |
O(1) | 仅有当参数中指定的Key存在时,该命令才会在其所 关联的List Value的头部插入参数中给出的Value,否 则将不会有任何操作发生。 |
插入后 链表中 元素的 数量。 |
LRANGE key start stop |
O(S+N) | 时间复杂度中的S为start参数表示的偏移量,N表示 元素的数量。该命令的参数 start和end都是0- based。即0表示链表头部(leftmost)的第一个元素。 其中start的值也可以为负值,-1将表示链表中的最后 一 个元素,即尾部元素,-2表示倒数第二个并以此 类推。该命令在获取元素时,start和end位置上的元 素也会被取出。如果start的值大于链表中元素 的数 量,空链表将会被返回。如果end的值大于元素的数 量,该命令则获取从start(包括start)开始,链表中剩 余的所有元素。 |
返回指 定范围 内元素 的列 表。 |
LPOP key | O(1) | 返回并弹出指定Key关联的链表中的第一个元素,即 头部元素,。如果该Key不存,返回nil。 |
链表头 部的元 素。 |
LLEN key | O(1) | 返回指定Key关联的链表中元素的数量,如果该Key 不存在,则返回0。如果与该Key关联的Value的类型 不是链表,则返回相关的错误信息。 |
链表中 元素的 数量。 |
LREM key count value |
O(N) | 时间复杂度中N表示链表中元素的数量。在指定Key 关联的链表中,删除前 count个值等于value的元 素。如果count大于0,从头向尾遍历并删除,如果 count小于0,则从尾向头遍历并删除。如果count等 于0, 则删除链表中所有等于value的元素。如果指 定的Key不存在,则直接返回0。 |
返回被 删除的 元素数 量。 |
LSET key index value |
O(N) | 时间复杂度中N表示链表中元素的数量。但是设定头 部或尾部的元素时,其时间复杂度为O(1)。设定链表 中指定位置的值为新值,其中0表示第一个元素,即 头部元素,-1表示尾部元素。如果索引值Index超出 了链表中元素的数量范围,该命令将返回相关的错误 信息。 |
|
LINDEX key index |
O(N) | 时间复杂度中N表示在找到该元素时需要遍历的元素 数量。对于头部或尾部元素,其时 间复杂度为 O(1)。该命令将返回链表中指定位置(index)的元 素,index是0-based,表示头部元素,如果index 为-1,表示尾部元 素。如果与该Key关联的不是链 表,该命令将返回相关的错误信息。 |
返回请 求的元 素,如 果 index 超出范 围,则 返回 nil。 |
LTRIM key start stop |
O(N) | N表示被删除的元素数量。该命令将仅保留指定范围 内的元素,从而保证链接中的元素 数量相对恒定。 start和stop参数都是0-based,0表示头部元素。和 其他命令一样,start和stop也可以为负值,-1表示 尾部元素。如 果start大于链表的尾部,或start大于 stop,该命令不错报错,而是返回一个空的链表,与 此同时该Key也将被删除。如果stop大于元素的数 量,则保留从start开始剩余的所有元素。 |
|
LINSERT key BEFORE|AFTER pivot value |
O(N) | 时间复杂度中N表示在找到该元素pivot之前需要遍历 的元素数量。这样意味着如 果pivot位于链表的头部 或尾部时,该命令的时间复杂度为O(1)。该命令的功 能是在pivot元素的前面或后面插入参数中的元素 value。如果 Key不存在,该命令将不执行任何操 作。如果与Key关联的Value类型不是链表,相关的 错误信息将被返回。 |
成功插 入后链 表中元 素的数 量,如 果没有 找到 pivot, 返 回-1, 如果 key不 存在, 返回 0。 |
RPUSH key value [value ...] |
O(1) | 在指定Key所关联的List Value的尾部插入参数中给 出的所有Values。如果该Key不存在,该命令将在插 入之前创建一个与该Key关联的空链表,之后再将数 据从链表的尾部插入。如果该键的Value不是链表类 型,该命令将返回相关的错误信息。 |
插入后 链表中 元素的 数量。 |
RPUSHX key value |
O(1) | 仅有当参数中指定的Key存在时,该命令才会在其所 关联的List Value的尾部插入参数中给出的Value,否 则将不会有任何操作发生。 |
插入后 链表中 元素的 数量。 |
RPOP key | O(1) | 返回并弹出指定Key关联的链表中的最后一个元素, 即尾部元素,。如果该Key不存,返回nil。 |
链表尾 部的元 素。 |
RPOPLPUSH source destination |
O(1) | 原子性的从与source键关联的链表尾部弹出一个元 素,同时再将弹出的元素插入 到与destination键关 联的链表的头部。如果source键不存在,该命令将 返回nil,同时不再做任何其它的操作了。如果 source和 destination是同一个键,则相当于原子性 的将其关联链表中的尾部元素移到该链表的头部。 |
返回弹 出和插 入的元 素。 |
#在Shell提示符下启动redis客户端工具。
/>redis-cli
redis 127.0.0.1:6379>del mykey
(integer) 1
#mykey键并不存在,该命令会创建该键及与其关联的List,之后在将参数中的values从左到右依次插入。
redis 127.0.0.1:6379>lpush mykey a b c d
(integer) 4
#取从位置0开始到位置2结束的3个元素。
redis 127.0.0.1:6379> lrange mykey 0 2
1) "d"
2) "c"
3) "b"
#取链表中的全部元素,其中0表示第一个元素,-1表示最后一个元素。
redis 127.0.0.1:6379> lrange mykey 0 -1
1) "d"
2) "c"
3) "b"
4) "a"
#mykey2键此时并不存在,因此该命令将不会进行任何操作,其返回值为0。
redis 127.0.0.1:6379> lpushx mykey2 e
(integer) 0
#可以看到mykey2没有关联任何List Value。
redis 127.0.0.1:6379>lrange mykey2 0 -1
(empty list or set)
#mykey键此时已经存在,所以该命令插入成功,并返回链表中当前元素的数量。
redis 127.0.0.1:6379> lpushx mykey e
(integer) 5
#获取该键的List Value的头部元素。
redis 127.0.0.1:6379> lrange mykey 0 0
1) "e"
redis 127.0.0.1:6379>lpush mykey a b c d
(integer) 4
redis 127.0.0.1:6379>lpop mykey
"d"
redis 127.0.0.1:6379>lpop mykey
"c"
#在执行lpop命令两次后,链表头部的两个元素已经被弹出,此时链表中元素的数量是2
redis 127.0.0.1:6379>llen mykey
(integer) 2
#为后面的示例准备测试数据。
redis 127.0.0.1:6379>lpush mykey a b c d a c
(integer) 6
#从头部(left)向尾部(right)变量链表,删除2个值等于a的元素,返回值为实际删除的数量。
redis 127.0.0.1:6379> lrem mykey 2 a
(integer) 2
#看出删除后链表中的全部元素。
redis 127.0.0.1:6379> lrange mykey 0 -1
1) "c"
2) "d"
3) "c"
4) "b"
#获取索引值为1(头部的第二个元素)的元素值。
redis 127.0.0.1:6379> lindex mykey 1
"d"
#将索引值为1(头部的第二个元素)的元素值设置为新值e。
redis 127.0.0.1:6379> lset mykey 1 e
OK
#查看是否设置成功。
redis 127.0.0.1:6379> lindex mykey 1
"e"
#索引值6超过了链表中元素的数量,该命令返回nil。
redis 127.0.0.1:6379> lindex mykey 6
(nil)
#设置的索引值6超过了链表中元素的数量,设置失败,该命令返回错误信息。
redis 127.0.0.1:6379>lset mykey 6 hh
(error) ERR index out of range
#仅保留索引值0到2之间的3个元素,注意第0个和第2个元素均被保留。
redis 127.0.0.1:6379> ltrim mykey 0 2
OK
#查看trim后的结果。
redis 127.0.0.1:6379> lrange mykey 0 -1
1) "c"
2) "e"
3) "c"
#删除该键便于后面的测试。
redis 127.0.0.1:6379> del mykey
(integer) 1
#为后面的示例准备测试数据。
redis 127.0.0.1:6379>lpush mykey a b c d e
(integer) 5
#在a的前面插入新元素a1。
redis 127.0.0.1:6379> linsert mykey before a a1
(integer) 6
#查看是否插入成功,从结果看已经插入。注意lindex的index值是0-based。
redis 127.0.0.1:6379>lindex mykey 0
"e"
#在e的后面插入新元素e2,从返回结果看已经插入成功。
redis 127.0.0.1:6379> linsert mykey after e e2
(integer) 7
#再次查看是否插入成功。
redis 127.0.0.1:6379> lindex mykey 1
"e2"
#在不存在的元素之前或之后插入新元素,该命令操作失败,并返回-1。
redis 127.0.0.1:6379>linsert mykey after k a
(integer) -1
#为不存在的Key插入新元素,该命令操作失败,返回0。
redis 127.0.0.1:6379> linsert mykey1 after a a2
(integer) 0
#删除该键,以便于后面的测试。
redis 127.0.0.1:6379> del mykey
(integer) 1
#从链表的尾部插入参数中给出的values,插入顺序是从左到右依次插入。
redis 127.0.0.1:6379>rpush mykey a b c d
(integer) 4
#通过lrange的可以获悉rpush在插入多值时的插入顺序。
redis 127.0.0.1:6379> lrange mykey 0 -1
1) "a"
在Redis中,我们可以将Set类型看作为没有排序的字符集合,和List类型一样,我们也可以在该类型的数据值上执行添加、删除或判断某一元素是否存 在等操作。需要说明的是,这些操作的时间复杂度为O(1),即常量时间内完成次操作。Set可包含的最大元素数量是4294967295。和List类型不同的是,这一点和C++标准库中的set容器是完全相同的。换句话说,如果多次添加相同元素,Set 中将仅保留该元素的一份拷贝。和List类型相比,Set类型在功能上还存在着一个非常重要的特性,即在服务器端完成多个Sets之间的聚合计算操作,如 unions、intersections和differences。由于这些操作均在服务端完成,因此效率极高,而且也节省了大量的网络IO开销。
命令原型 | 时间复 杂度 |
命令描述 | 返回值 |
SADD key member [member ...] |
O(N) | 时间复杂度中的N表示操作的成员数量。如果在插 入的过程用,参数中有的成员在 Set中已经存在, 该成员将被忽略,而其它成员仍将会被正常插入。 如果执行该命令之前,该Key并不存在,该命令将 会创建一个新的Set,此后再将参数中 的成员陆续 插入。如果该Key的Value不是Set类型,该命令将 返回相关的错误信息。 |
本次操 作实际 插入的 成员数 量。 |
SCARD key | O(1) | 获取Set中成员的数量。 | 返回 Set中 成员的 数量, 如果该 Key并 不存 在,返 回0。 |
SISMEMBER key member |
O(1) | 判断参数中指定成员是否已经存在于与Key相关联 的Set集合中 |
1表示 已经存 在,0 表示不 存在, 或该 Key本 身并不 存在。 |
SMEMBERS key | O(N) | 时间复杂度中的N表示Set中已经存在的成员数量。 获取与该Key关联的Set中所有的成员。 |
返回 Set中 所有的 成员。 |
SPOP key | O(1) | 随机的移除并返回Set中的某一成员。 由于Set中元 素的布局不受外部控制,因此无法像List那样确定哪 个元素位于Set的头部或者尾部。 |
返回移 除的成 员,如 果该 Key并 不存 在,则 返回 nil。 |
SREM key member [member ...] |
O(N) | 时间复杂度中的N表示被删除的成员数量。从与Key 关联的Set中删除参数中指定的成员,不存在的参数 成员将被忽略,如果该Key并不存在,将视为空Set 处理。 |
从Set 中实际 移除的 成员数 量,如 果没有 则返回 0。 |
SRANDMEMBER key |
O(1) | 和SPOP一样,随机的返回Set中的一个成员,不同 的是该命令并不会删除返回的成员。 |
返回随 机位置 的成 员,如 果Key 不存在 则返回 nil。 |
SMOVE source destination member |
O(1) | 原子性的将参数中的成员从source键移入到 destination键所关联的 Set中。因此在某一时刻, 该成员或者出现在source中,或者出现在 destination中。如果该成员在source中并不存在, 该命令将不会再 执行任何操作并返回0,否则,该 成员将从source移入到destination。如果此时该成 员已经在destination中存在,那么该命令仅是 将该 成员从source中移出。如果和Key关联的Value不是 Set,将返回相关的错误信息。 |
1表示 正常移 动,0 表示 source 中并不 包含参 数成 员。 |
SDIFF key [key ...] |
O(N) | 时间复杂度中的N表示所有Sets中成员的总数量。 返回参数中第一个Key所关联的Set和其后所有Keys 所关联的Sets中成员的差异。如果Key不存在,则 视为空Set。 |
差异结 果成员 的集 合。 |
SDIFFSTORE destination key [key ...] |
O(N) | 该命令和SDIFF命令在功能上完全相同,两者之间唯 一的差别是SDIFF返回差异的结果成员,而该命令将 差异成员存储在destination关联的Set中。如果 destination键已经存在,该操作将覆盖它的成员。 |
返回差 异成员 的数 量。 |
SINTER key [key ...] |
O(N*M) | 时间复杂度中的N表示最小Set中元素的数量,M则 表示参数中Sets的数量。该命令将返回参数中所有 Keys关联的Sets中成员的交集。因此如果参数中任 何一个Key关联的Set为空,或某一Key不存在,那 么该命令的结果将为空集。 |
交集结 果成员 的集 合。 |
SINTERSTORE destination key [key ...] |
O(N*M) | 该命令和SINTER命令在功能上完全相同,两者之间 唯一的差别是SINTER返回交集的结果成员,而该命 令将交集成员存储在destination关联的Set中。如 果destination键已经存在,该操作将覆盖它的成 员。 |
返回交 集成员 的数 量。 |
SUNION key [key ...] |
O(N) | 时间复杂度中的N表示所有Sets中成员的总数量。 该命令将返回参数中所有Keys关联的Sets中成员的 并集。 |
并集结 果成员 的集 合。 |
SUNIONSTORE destination key [key ...] |
O(N) | 该命令和SUNION命令在功能上完全相同,两者之 间唯一的差别是SUNION返回并集的结果成员,而 该命令将并集成员存储在destination关联的Set 中。如果destination键已经存在,该操作将覆盖它 的成员。 |
返回并 集成员 的数 量。 |
#在Shell命令行下启动Redis的客户端程序。
/> redis-cli
#插入测试数据,由于该键myset之前并不存在,因此参数中的三个成员都被正常插入。
redis 127.0.0.1:6379>sadd myset a b c
(integer) 3
#由于参数中的a在myset中已经存在,因此本次操作仅仅插入了d和e两个新成员。
redis 127.0.0.1:6379>sadd myset a d e
(integer) 2
#判断a是否已经存在,返回值为1表示存在。
redis 127.0.0.1:6379>sismember myset a
(integer) 1
#判断f是否已经存在,返回值为0表示不存在。
redis 127.0.0.1:6379>sismember myset f
(integer) 0
#通过smembers命令查看插入的结果,从结果可以,输出的顺序和插入顺序无关。
redis 127.0.0.1:6379> smembers myset
1) "c"
2) "d"
3) "a"
4) "b"
5) "e"
#获取Set集合中元素的数量。
redis 127.0.0.1:6379>scard myset
(integer) 5
#删除该键,便于后面的测试。
redis 127.0.0.1:6379>del myset
(integer) 1
#为后面的示例准备测试数据。
redis 127.0.0.1:6379>sadd myset a b c d
(integer) 4
#查看Set中成员的位置。
redis 127.0.0.1:6379> smembers myset
1) "c"
2) "d"
3) "a"
4) "b"
#从结果可以看出,该命令确实是随机的返回了某一成员。
redis 127.0.0.1:6379>srandmember myset
"c"
#Set中尾部的成员b被移出并返回,事实上b并不是之前插入的第一个或最后一个成员。
redis 127.0.0.1:6379>spop myset
"b"
#查看移出后Set的成员信息。
redis 127.0.0.1:6379> smembers myset
1) "c"
2) "d"
3) "a"
#从Set中移出a、d和f三个成员,其中f并不存在,因此只有a和d两个成员被移出,返回为2。
redis 127.0.0.1:6379>srem myset a d f
(integer) 2
#查看移出后的输出结果。
redis 127.0.0.1:6379>smembers myset
1) "c"
#为后面的smove命令准备数据。
redis 127.0.0.1:6379>sadd myset a b
(integer) 2
redis 127.0.0.1:6379>sadd myset2 c d
(integer) 2
#将a从myset移到myset2,从结果可以看出移动成功。
redis 127.0.0.1:6379>smove myset myset2 a
(integer) 1
#再次将a从myset移到myset2,由于此时a已经不是myset的成员了,因此移动失败并返回0。
redis 127.0.0.1:6379>smove myset myset2 a
(integer) 0
#分别查看myset和myset2的成员,确认移动是否真的成功。
redis 127.0.0.1:6379>smembers myset
1) "b"
redis 127.0.0.1:6379> smembers myset2
1) "c"
2) "d"
3) "a"
#为后面的命令准备测试数据。
redis 127.0.0.1:6379>sadd myset a b c d
(integer) 4
redis 127.0.0.1:6379> sadd myset2 c
(integer) 1
redis 127.0.0.1:6379>sadd myset3 a c e
(integer) 3
#myset和myset2相比,a、b和d三个成员是两者之间的差异成员。再用这个结果继续和myset3进行差异比
较,b和d是myset3不存在的成员。
redis 127.0.0.1:6379>sdiff myset myset2 myset3
1) "d"
2) "b"
#将3个集合的差异成员存在在diffkey关联的Set中,并返回插入的成员数量。
redis 127.0.0.1:6379>sdiffstore diffkey myset myset2 myset3
(integer) 2
#查看一下sdiffstore的操作结果。
redis 127.0.0.1:6379>smembers diffkey
1) "d"
2) "b"
#从之前准备的数据就可以看出,这三个Set的成员交集只有c。
redis 127.0.0.1:6379>sinter myset myset2 myset3
1) "c"
#将3个集合中的交集成员存储到与interkey关联的Set中,并返回交集成员的数量。
redis 127.0.0.1:6379> sinterstore interkey myset myset2 myset3
(integer) 1
#查看一下sinterstore的操作结果。
redis 127.0.0.1:6379>smembers interkey
1) "c"
#获取3个集合中的成员的并集。
redis 127.0.0.1:6379>sunion myset myset2 myset3
1) "b"
2) "c"
3) "d"
4) "e"
5) "a"
#将3个集合中成员的并集存储到unionkey关联的set中,并返回并集成员的数量。
redis 127.0.0.1:6379>sunionstore unionkey myset myset2 myset3
(integer) 5
#查看一下suiionstore的操作结果。
redis 127.0.0.1:6379>smembers unionkey
1) "b"
2) "c"
3) "d"
4) "e"
5) "a"
1). 可以使用Redis的Set数据类型跟踪一些唯一性数据,比如访问某一博客的唯一IP地址信息。对于此场景,我们仅需在每次访问该博客时将访问者的IP存入Redis中,Set数据类型会自动保证IP地址的唯一性。
2). 充分利用Set类型的服务端聚合操作方便、高效的特性,可以用于维护数据对象之间的关联关系。比如所有购买某一电子设备的客户ID被存储在一个指定的 Set中,而购买另外一种电子产品的客户ID被存储在另外一个Set中,如果此时我们想获取有哪些客户同时购买了这两种商品时,Set的 intersections命令就可以充分发挥它的方便和效率的优势了。
1、设计四个好友
[root@localhost ~]# redis-cli
127.0.0.1:6379> set it_user:id:1:username tom
OK
127.0.0.1:6379> set it_user:id:1:email tom@qq.ocm
OK
127.0.0.1:6379> set it_user:id:2:username john
OK
127.0.0.1:6379> set it_user:id:2:email john@qq.ocm
OK
127.0.0.1:6379> set it_user:id:3:username bob
OK
127.0.0.1:6379> set it_user:id:3:email bob@qq.com
OK
127.0.0.1:6379> set it_user:id:4:username smith
OK
127.0.0.1:6379> set it_user:id:4:email smith@qq.com
OK
127.0.0.1:6379> keys it_user:id*
1) "it_user:id:4:username"
2) "it_user:id:1:username"
3) "it_user:id:2:username"
4) "it_user:id:2:email"
5) "it_user:id:1:email"
6) "it_user:id:3:email"
7) "it_user:id:4:email"
8) "it_user:id:3:username"
2、设定好友集合
1号好友为2号和3号
127.0.0.1:6379> sadd set:user:id:1:friend 2
(integer) 1
127.0.0.1:6379> sadd set:user:id:1:friend 3
(integer) 1
127.0.0.1:6379> SMEMBERS set:user:id:1:friend
1) "2"
2) "3"
4号好友为3号
127.0.0.1:6379> sadd set:user:id:4:friend 3
(integer) 1
127.0.0.1:6379> SMEMBERS set:user:id:4:friend
1) "3"
3、好友关系
共同好友(交集)
127.0.0.1:6379> SINTER set:user:id:1:friend set:user:id:4:friend
1) "3"
全部好友(并集)
127.0.0.1:6379> sunion set:user:id:1:friend set:user:id:4:friend
1) "2"
2) "3"
推荐好友(差集)
127.0.0.1:6379> SDIFF set:user:id:1:friend set:user:id:4:friend
1) "2"
一个简单的实例 sns的常用功能,获取共同好友
Sorted-Sets和Sets类型极为相似,它们都是字符串的集合,都不允许重复的成员出现在一个Set中。它们之间的主要差别是Sorted- Sets中的每一个成员都会有一个分数(score)与之关联,Redis正是通过分数来为集合中的成员进行从小到大的排序。然而需要额外指出的是,尽管 Sorted-Sets中的成员必须是唯一的,但是分数(score)却是可以重复的。
在Sorted-Set中添加、删除或更新一个成员都是非常快速的操作,其时间复杂度为集合中成员数量的对数。由于Sorted-Sets中的成员在集 合中的位置是有序的,因此,即便是访问位于集合中部的成员也仍然是非常高效的。事实上,Redis所具有的这一特征在很多其它类型的数据库中是很难实现 的,换句话说,在该点上要想达到和Redis同样的高效,在其它数据库中进行建模是非常困难的。
命令原型 | 时间复杂度 | 命令描述 | 返回值 |
ZADD key score member [score] [member] |
O(log(N)) | 时间复杂度中的N表示Sorted-Sets中成 员的数量。添加参数中指定的所有 成员 及其分数到指定key的Sorted-Set中,在 该命令中我们可以指定多组 score/member作为参数。如果在添加时 参数中的某一成员已经存 在,该命令将 更新此成员的分数为新值,同时再将该 成员基于新值重新排序。如果键不存 在,该命令将为该键创建一个新的 Sorted-Sets Value,并将 score/member对插入其中。如果该键已 经存在,但是与其关联的Value不是 Sorted-Sets类型,相关的错误信息将被 返回。 |
本次操 作实际 插入的 成员数 量。 |
ZCARD key | O(1) | 获取与该Key相关联的Sorted-Sets中包 含的成员数量。 |
返回 Sorted- Sets中 的成员 数量, 如果该 Key不 存在, 返回 0。 |
ZCOUNT key min max | O(log(N)+M) | 时间复杂度中的N表示Sorted-Sets中成 员的数量,M则表示min和max之间元素 的数量。该命令用于获取分数(score)在 min和max之间的成员数量。针对min和 max参数需要额外说明的是,-inf和+inf 分别表示Sorted-Sets中分数的最高值和 最低值。缺省情况下,min和max表示的 范围是闭区间范围,即min <= score <= max内的成员将被返回。然而我们可以 通过在min和max的前面添加"("字符来表 示开区间,如(min max表示min < score <= max,而(min (max表示min < score < max。 |
分数指 定范围 内成员 的数 量。 |
ZINCRBY key increment member |
O(log(N)) | 时间复杂度中的N表示Sorted-Sets中成 员的数量。该命令将为指定Key 中的指定 成员增加指定的分数。如果成员不存 在,该命令将添加该成员并假设其初始 分数为0,此后再将其分数加上 increment。如果Key不存,该命令 将创 建该Key及其关联的Sorted-Sets,并包 含参数指定的成员,其分数为increment 参数。如果与该Key关联的不是Sorted- Sets类型,相关的错误信息将被返回。 |
以字符 串形式 表示的 新分 数。 |
ZRANGE key start stop [WITHSCORES] |
O(log(N)+M) | 时间复杂度中的N表示Sorted-Set中成员 的数量,M则表示返回的成员数 量。该 命令返回顺序在参数start和stop指定范 围内的成员,这里start和stop参数都是 0-based,即0表示第一个成员,-1表示 最后一 个成员。如果start大于该Sorted- Set中的最大索引值,或start > stop,此 时一个空集合将被返回。如果stop大于 最大索引值,该命令将返回从start到集 合的最后一个成员。如果命令中带有可 选参数WITHSCORES选项,该命令在返 回的结果中将包含每个成员的分数值, 如value1,score1,value2,score2...。 |
返回索 引在 start和 stop之 间的成 员列 表。 |
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] |
O(log(N)+M) | 时间复杂度中的N表示Sorted-Set中成员 的数量,M则表示返回的成员数 量。该 命令将返回分数在min和max之间的所有 成员,即满足表达式min <= score <= max的成员,其中返回的成员是按照其 分数从低到高的顺序返回,如果成员具 有相同的分数,则按成员的字典顺序返 回。可选参数LIMIT用于限制返回成员的 数量范围。可选参数offset表示从符合条 件的第offset个成员开始返回,同时返回 count个成员。可选参数WITHSCORES的 含义参照 ZRANGE中该选项的说明。最 后需要说明的是参数中min和max的规则 可参照命令ZCOUNT。 |
返回分 数在指 定范围 内的成 员列 表。 |
ZRANK key member | O(log(N)) | 时间复杂度中的N表示Sorted-Set中成员 的数量。Sorted-Set中的成员都是按照分 数从低到高的顺序存储,该命令将返回 参数中指定成员的位置值,其中0表示第 一个成员,它是Sorted-Set中分数最低的 成员。 |
如果该 成员存 在,则 返回它 的位置 索引 值。否 则返回 nil。 |
ZREM key member [member ...] |
O(M log(N)) | 时间复杂度中N表示Sorted-Set中成员的 数量,M则表示被删除的成员数量。该命 令将移除参数中指定的成员,其中不存 在的成员将被忽略。如果与该Key关联的 Value不是Sorted-Set,相应的错误信息 将被返回。 |
实际被 删除的 成员数 量。 |
ZREVRANGE key start stop [WITHSCORES] |
O(log(N)+M) | 时间复杂度中的N表示Sorted-Set中成员 的数量,M则表示返回的成员数量。该命 令的功能和ZRANGE基本相同,唯一的差 别在于该命令是通过反向排序获取指定 位置的成员,即从高到低的顺序。如果 成员具有相同的分数,则按降序字典顺 序排序。 |
返回指 定的成 员列 表。 |
ZREVRANK key member |
O(log(N)) | 时间复杂度中的N表示Sorted-Set中成员 的数量。该命令的功能和ZRANK基本相 同,唯一的差别在于该命令获取的索引 是从高到低排序后的位置,同样0表示第 一个元素,即分数最高的成员。 |
如果该 成员存 在,则 返回它 的位置 索引 值。否 则返回 nil。 |
ZSCORE key member | O(1) | 获取指定Key的指定成员的分数。 | 如果该 成员存 在,以 字符串 的形式 返回其 分数, 否则返 回nil。 |
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count] |
O(log(N)+M) | 时间复杂度中的N表示Sorted-Set中成员 的数量,M则表示返回的成员数量。该命 令除了排序方式是基于从高到低的分数 排序之外,其它功能和参数含义均与 ZRANGEBYSCORE相同。 |
返回分 数在指 定范围 内的成 员列 表。 |
ZREMRANGEBYRANK key start stop |
O(log(N)+M) | 时间复杂度中的N表示Sorted-Set中成员 的数量,M则表示被删除的成员数量。删 除索引位置位于start和stop之间的成 员,start和stop都是0-based,即0表示 分数最低的成员,-1表示最后一个成员, 即分数最高的成员。 |
被删除 的成员 数量。 |
ZREMRANGEBYSCORE key min max |
O(log(N)+M) | 时间复杂度中的N表示Sorted-Set中成员 的数量,M则表示被删除的成员数量。删 除分数在min和max之间的所有成员,即 满足表达式min <= score <= max的所有 成员。对于min和max参数,可以采用开 区间的方式表示,具体规则参照 ZCOUNT。 |
被删除 的成员 数量。 |
#在Shell的命令行下启动Redis客户端工具。
/>redis-cli
#添加一个分数为1的成员。
redis 127.0.0.1:6379> zadd myzset 1 "one"
(integer) 1
#添加两个分数分别是2和3的两个成员。
redis 127.0.0.1:6379>zadd myzset 2 "two" 3 "three"
(integer) 2
#0表示第一个成员,-1表示最后一个成员。WITHSCORES选项表示返回的结果中包含每个成员及其分数,否则
只返回成员。
redis 127.0.0.1:6379>zrange myzset 0 -1 WITHSCORES
1) "one"
2) "1"
3) "two"
4) "2"
5) "three"
6) "3"
#获取成员one在Sorted-Set中的位置索引值。0表示第一个位置。
redis 127.0.0.1:6379>zrank myzset one
(integer) 0
#成员four并不存在,因此返回nil。
redis 127.0.0.1:6379>zrank myzset four
(nil)
#获取myzset键中成员的数量。
redis 127.0.0.1:6379> zcard myzset
(integer) 3
#返回与myzset关联的Sorted-Set中,分数满足表达式1 <= score <= 2的成员的数量。
redis 127.0.0.1:6379>zcount myzset 1 2
(integer) 2
#删除成员one和two,返回实际删除成员的数量。
redis 127.0.0.1:6379>zrem myzset one two
(integer) 2
#查看是否删除成功。
redis 127.0.0.1:6379>zcard myzset
(integer) 1
#获取成员three的分数。返回值是字符串形式。
redis 127.0.0.1:6379>zscore myzset three
"3"
#由于成员two已经被删除,所以该命令返回nil。
redis 127.0.0.1:6379>zscore myzset two
(nil)
#将成员one的分数增加2,并返回该成员更新后的分数。
redis 127.0.0.1:6379>zincrby myzset 2 one
"3"
#将成员one的分数增加-1,并返回该成员更新后的分数。
redis 127.0.0.1:6379>zincrby myzset -1 one
"2"
#查看在更新了成员的分数后是否正确。
redis 127.0.0.1:6379>zrange myzset 0 -1 WITHSCORES
1) "one"
2) "2"
3) "two"
4) "2"
5) "three"
6) "3"
redis 127.0.0.1:6379>del myzset
(integer) 1
redis 127.0.0.1:6379>zadd myzset 1 one 2 two 3 three 4 four
(integer) 4
#获取分数满足表达式1 <= score <= 2的成员。
redis 127.0.0.1:6379> zrangebyscore myzset 1 2
1) "one"
2) "two"
#获取分数满足表达式1 < score <= 2的成员。
redis 127.0.0.1:6379>zrangebyscore myzset (1 2
1) "two"
#-inf表示第一个成员,+inf表示最后一个成员,limit后面的参数用于限制返回成员的自己,
#2表示从位置索引(0-based)等于2的成员开始,去后面3个成员。
redis 127.0.0.1:6379>zrangebyscore myzset -inf +inf limit 2 3
1) "three"
2) "four"
#删除分数满足表达式1 <= score <= 2的成员,并返回实际删除的数量。
redis 127.0.0.1:6379>zremrangebyscore myzset 1 2
(integer) 2
#看出一下上面的删除是否成功。
redis 127.0.0.1:6379>zrange myzset 0 -1
1) "three"
2) "four"
#删除位置索引满足表达式0 <= rank <= 1的成员。
redis 127.0.0.1:6379>zremrangebyrank myzset 0 1
(integer) 2
#查看上一条命令是否删除成功。
redis 127.0.0.1:6379>zcard myzset
(integer) 0
#为后面的示例准备测试数据。
redis 127.0.0.1:6379>del myzset
(integer) 0
redis 127.0.0.1:6379>zadd myzset 1 one 2 two 3 three 4 four
(integer) 4
#以位置索引从高到低的方式获取并返回此区间内的成员。
redis 127.0.0.1:6379>zrevrange myzset 0 -1 WITHSCORES
1) "four"
2) "4"
3) "three"
4) "3"
5) "two"
6) "2"
7) "one"
8) "1"
#由于是从高到低的排序,所以位置等于0的是four,1是three,并以此类推。
redis 127.0.0.1:6379>zrevrange myzset 1 3
1) "three"
2) "two"
3) "one"
#由于是从高到低的排序,所以one的位置是3。
redis 127.0.0.1:6379>zrevrank myzset one
(integer) 3
#由于是从高到低的排序,所以four的位置是0。
redis 127.0.0.1:6379>zrevrank myzset four
(integer) 0
#获取分数满足表达式3 >= score >= 0的成员,并以相反的顺序输出,即从高到底的顺序。
redis 127.0.0.1:6379>zrevrangebyscore myzset 3 0
1) "three"
2) "two"
3) "one"
#该命令支持limit选项,其含义等同于zrangebyscore中的该选项,只是在计算位置时按照相反的顺序计算
和获取。
redis 127.0.0.1:6379> zrevrangebyscore myzset 4 0 limit 1 2
1) "three"
2) "two"
1). 可以用于一个大型在线游戏的积分排行榜。每当玩家的分数发生变化时,可以执行ZADD命令更新玩家的分数,此后再通过ZRANGE命令获取积分TOP TEN的用户信息。当然我们也可以利用ZRANK命令通过username来获取玩家的排行信息。最后我们将组合使用ZRANGE和ZRANK命令快速的 获取和某个玩家积分相近的其他用户的信息。
2). Sorted-Sets类型还可用于构建索引数据。
在前面主要讲述的是与Redis数据类型相关的命令,如String、List、Set、Hashes和Sorted-Set。这些命 令都具有一个共同点,即所有的操作都是针对与Key关联的Value的。下面主要讲述与Key相关的Redis命令。学习这些命令对于学习 Redis是非常重要的基础,也是能够充分挖掘Redis潜力的利器。
命令原型 | 时间复杂度 | 命令描述 | 返回值 |
KEYS pattern | O(N) | 时间复杂度中的N表示数据库中Key的数 量。获取所有匹配pattern参数的Keys。需 要说明的是,在我们的正常操作中应该尽 量避免对该命令的调用,因为对于大型数 据库而言,该命令是非常耗时的,对Redis 服务器的性能打击也是比较大的。pattern 支持glob-style的通配符格式,如*表示任 意一个或多个字符,?表示任意字符,[abc] 表示方括号中任意一个字母。 |
匹配模 式的键 列表。 |
DEL key [key ...] | O(N) | 时间复杂度中的N表示删除的Key数量。从 数据库删除中参数中指定的keys,如 果指 定键不存在,则直接忽略。还需要另行指 出的是,如果指定的Key关联的数据类型不 是String类型,而是List、Set、Hashes和 Sorted Set等容器类型,该命令删除每个键 的时间复杂度为O(M),其中M表示容器中 元素的数量。而对于String类型的Key,其 时间复杂度为O(1)。 |
实际被 删除的 Key数 量。 |
EXISTS key | O(1) | 判断指定键是否存在 | 1表示存 在,0表 示不存 在。 |
MOVE key db | O(1) | 将当前数据库中指定的键Key移动到参数中 指定的数据库中。如果该Key在目标数据库 中已经存在,或者在当前数据库中并不存 在,该命令将不做任何操作并返回0。 |
移动成 功返回 1,否则 0。 |
RENAME key newkey |
O(1) | 为指定指定的键重新命名,如果参数中的 两个Keys的命令相同,或者是源Key不存 在,该命令都会返回相关的错误信息。如 果newKey已经存在,则直接覆盖。 |
|
RENAMENX key newkey |
O(1) | 如果新值不存在,则将参数中的原值修改 为新值。其它条件和RENAME一致。 |
1表示修 改成 功,否 则0。 |
PERSIST key | O(1) | 如果Key存在过期时间,该命令会将其过期 时间消除,使该Key不再有超时,而是可以 持久化存储。 |
1表示 Key的过 期时间 被移 出,0表 示该Key 不存在 或没有 过期时 间。 |
EXPIRE key seconds |
O(1) | 该命令为参数中指定的Key设定超时的秒 数,在超过该时间后,Key被自动的删除。 如果该Key在超时之前被修改,与该键关联 的超时将被移除。 |
1表示超 时被设 置,0则 表示Key 不存 在,或 不能被 设置。 |
EXPIREAT key timestamp |
O(1) | 该命令的逻辑功能和EXPIRE完全相同,唯 一的差别是该命令指定的超时时间是绝对 时间,而不是相对时间。该时间参数是 Unix timestamp格式的,即从1970年1月1 日开始所流经的秒数。 |
1表示超 时被设 置,0则 表示Key 不存 在,或 不能被 设置。 |
TTL key | O(1) | 获取该键所剩的超时描述。 | 返回所 剩描 述,如 果该键 不存在 或没有 超时设 置,则 返 回-1。 |
RANDOMKEY | O(1) | 从当前打开的数据库中随机的返回一个 Key。 |
返回的 随机 键,如 果该数 据库是 空的则 返回 nil。 |
TYPE key | O(1) | 获取与参数中指定键关联值的类型,该命 令将以字符串的格式返回。 |
返回的 字符串 为 string、 list、 set、 hash和 zset, 如果key 不存在 返回 none。 |
SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination] |
O(N+M*log(M)) | 这个命令相对来说是比较复杂的,因此我 们这里只是给出最基本的用法,有兴趣的 网友可以去参考redis的官方文档。 |
返回排 序后的 原始列 表。 |
#在Shell命令行下启动Redis客户端工具。
/> redis-cli
#清空当前选择的数据库,以便于对后面示例的理解。
redis 127.0.0.1:6379>flushdb
OK
#添加String类型的模拟数据。
redis 127.0.0.1:6379>set mykey 2
OK
redis 127.0.0.1:6379>set mykey2 "hello"
OK
#添加Set类型的模拟数据。
redis 127.0.0.1:6379>sadd mysetkey 1 2 3
(integer) 3
#添加Hash类型的模拟数据。
redis 127.0.0.1:6379>hset mmtest username "stephen"
(integer) 1
#根据参数中的模式,获取当前数据库中符合该模式的所有key,从输出可以看出,该命令在执行时并不区分与
Key关联的Value类型。
redis 127.0.0.1:6379>keys my*
1) "mysetkey"
2) "mykey"
3) "mykey2"
#删除了两个Keys。
redis 127.0.0.1:6379>del mykey mykey2
(integer) 2
#查看一下刚刚删除的Key是否还存在,从返回结果看,mykey确实已经删除了。
redis 127.0.0.1:6379>exists mykey
(integer) 0
#查看一下没有删除的Key,以和上面的命令结果进行比较。
redis 127.0.0.1:6379>exists mysetkey
(integer) 1
#将当前数据库中的mysetkey键移入到ID为1的数据库中,从结果可以看出已经移动成功。
redis 127.0.0.1:6379>move mysetkey 1
(integer) 1
#打开ID为1的数据库。
redis 127.0.0.1:6379> select 1
OK
#查看一下刚刚移动过来的Key是否存在,从返回结果看已经存在了。
redis 127.0.0.1:6379[1]>exists mysetkey
(integer) 1
#在重新打开ID为0的缺省数据库。
redis 127.0.0.1:6379[1]>select 0
OK
#查看一下刚刚移走的Key是否已经不存在,从返回结果看已经移走。
redis 127.0.0.1:6379>exists mysetkey
(integer) 0
#准备新的测试数据。
redis 127.0.0.1:6379>set mykey "hello"
OK
#将mykey改名为mykey1
redis 127.0.0.1:6379> rename mykey mykey1
OK
#由于mykey已经被重新命名,再次获取将返回nil。
redis 127.0.0.1:6379>get mykey
(nil)
#通过新的键名获取。
redis 127.0.0.1:6379>get mykey1
"hello"
#由于mykey已经不存在了,所以返回错误信息。
redis 127.0.0.1:6379>rename mykey mykey1
(error) ERR no such key
#为renamenx准备测试key
redis 127.0.0.1:6379>set oldkey "hello"
OK
redis 127.0.0.1:6379>set newkey "world"
OK
#由于newkey已经存在,因此该命令未能成功执行。
redis 127.0.0.1:6379>renamenx oldkey newkey
(integer) 0
#查看newkey的值,发现它也没有被renamenx覆盖。
redis 127.0.0.1:6379>get newkey
"world"
#为后面的示例准备的测试数据。
redis 127.0.0.1:6379>set mykey "hello"
OK
#将该键的超时设置为100秒。
redis 127.0.0.1:6379>expire mykey 100
(integer) 1
#通过ttl命令查看一下还剩下多少秒。
redis 127.0.0.1:6379>ttl mykey
(integer) 97
#立刻执行persist命令,该存在超时的键变成持久化的键,即将该Key的超时去掉。
redis 127.0.0.1:6379>persist mykey
(integer) 1
#ttl的返回值告诉我们,该键已经没有超时了。
redis 127.0.0.1:6379>ttl mykey
(integer) -1
#为后面的expire命令准备数据。
redis 127.0.0.1:6379> del mykey
(integer) 1
redis 127.0.0.1:6379>set mykey "hello"
OK
#设置该键的超时被100秒。
redis 127.0.0.1:6379>expire mykey 100
(integer) 1
#用ttl命令看一下当前还剩下多少秒,从结果中可以看出还剩下96秒。
redis 127.0.0.1:6379>ttl mykey
(integer) 96
#重新更新该键的超时时间为20秒,从返回值可以看出该命令执行成功。
redis 127.0.0.1:6379>expire mykey 20
(integer) 1
#再用ttl确认一下,从结果中可以看出果然被更新了。
redis 127.0.0.1:6379>ttl mykey
(integer) 17
#立刻更新该键的值,以使其超时无效。
redis 127.0.0.1:6379>set mykey "world"
OK
#从ttl的结果可以看出,在上一条修改该键的命令执行后,该键的超时也无效了。
redis 127.0.0.1:6379>ttl mykey
(integer) -1
#由于mm键在数据库中不存在,因此该命令返回none。
redis 127.0.0.1:6379>type mm
none
#mykey的值是字符串类型,因此返回string。
redis 127.0.0.1:6379>type mykey
string
#准备一个值是set类型的键。
redis 127.0.0.1:6379>sadd mysetkey 1 2
(integer) 2
#mysetkey的键是set,因此返回字符串set。
redis 127.0.0.1:6379>type mysetkey
set
#返回数据库中的任意键。
redis 127.0.0.1:6379>randomkey
"oldkey"
#清空当前打开的数据库。
redis 127.0.0.1:6379>flushdb
OK
#由于没有数据了,因此返回nil。
redis 127.0.0.1:6379>randomkey
(nil)
1、安装php-redis
[root@localhost ~]# yum install php-redis
2、准备php环境
[root@localhost ~]# yum install httpd php -y
3、启动测试apache和php协同
[root@localhost ~]# vim /var/www/html/phpinfo.php
[root@localhost ~]# systemctl start httpd
[root@localhost ~]# systemctl enable httpd
4、测试
连接到 redis 服务
[root@localhost ~]# vim /var/www/html/ping.php
connect('127.0.0.1', 6379);
echo "Connection to server sucessfully";
//查看服务是否运行
echo "Server is running: " . $redis->ping();
?>
[root@localhost ~]# elinks -dump http://localhost/ping.php
Connection to server sucessfullyServer is running: +PONG
Redis PHP String(字符串) 实例
[root@localhost ~]# vim /var/www/html/string.php
connect('127.0.0.1', 6379);
echo "Connection to server sucessfully";
//设置 redis 字符串数据
$redis->set("linux", "Linux Redis test");
// 获取存储的数据并输出
echo "Stored string in redis:: " . $redis->get("linux");
?>
[root@localhost ~]# elinks -dump http://localhost/string.php
Connection to server sucessfullyStored string in redis:: Linux Redis test
Redis PHP List(列表) 实例
[root@localhost ~]# vim /var/www/html/list.php
connect('127.0.0.1', 6379);
echo "Connection to server sucessfully";
//存储数据到列表中
$redis->lpush("test-list", "Redis");
$redis->lpush("test-list", "Mongodb");
$redis->lpush("test-list", "Mysql");
// 获取存储的数据并输出
$arList = $redis->lrange("test-list", 0 ,5);
echo "Stored string in redis";
print_r($arList);
?>
[root@localhost ~]# elinks -dump http://localhost/list.php
Connection to server sucessfullyStored string in redisArray ( [0] => Mysql
[1] => Mongodb [2] => Redis )
Redis PHP Keys 实例
[root@localhost ~]# vim /var/www/html/keys.php
connect('127.0.0.1', 6379);
echo "Connection to server sucessfully";
// 获取数据并输出
$arList = $redis->keys("*");
echo "Stored keys in redis:: ";
print_r($arList);
?>
[root@localhost ~]# elinks -dump http://localhost/keys.php
Connection to server sucessfullyStored keys in redis:: Array ( [0] =>
test-list [1] => linux )
1、安装python-redis
[root@localhost ~]# yum install python-redis -y
2、基本操作
[root@localhost ~]# vim python_redis.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#载入模块
import redis
#连接redis数据库
r = redis.Redis(host='127.0.0.1', port=6379,db=0)
#往redis中写数据
r.set('nvshen', 'hehe')
r['diaosi'] = 'yy'
r.set('xueba', 'xuexi')
r['xuezha'] = 'wan'
#查看对应的值
print 'nvshen', r.get('nvshen')
#查看数据库中有多少个key,多少条数据
print r.dbsize()
#将数据保存到硬盘中(保存时阻塞)
r.save()
#查看键值是否存在
print r.exists("doubi")
#列出所有键值
print r.keys()
#删除键值对应的数据
print r.delete('diaosi')
print r.delete('xuezha')
#删除当前数据库所有数据
r.flushdb()
[root@localhost ~]# python python_redis.py
nvshen hehe
4
False
['xuezha', 'xueba', 'diaosi', 'nvshen']
1
1
RESP.app (formerly Redis Desktop Manager) - GUI for Redis ® available on Windows, macOS, iPad and Linux.
redis desktop manager是一款功能强大的redis数据库管理软件,可以帮助用户轻松快速的查看与操控整个数据库。redis desktop manager不仅拥有十分简洁直观的操作界面,而且所有功能信息一目了然,是广大用户必备的数据库管理神器。
redis desktop manager具有操作简单、方便快捷、功能完善、性能稳定等优点,支持用户采用可视化操作界面对数据库进行各方面工作,不管是新手用户还是专业的开发人员,该软件都是你管理数据库的最佳帮手。
Redis Desktop Manager for windows是一款可以跨平台的redis可视化工具,兼容win、mac等操作系统,该工具可以说很大程度上弥补了memcached这类key/value存储的不足,为Java、C/C++、C#、PHP、JavaScript、Perl、Object-C、Python、Ruby、Erlang等开发语言提供了便利的客户端。
C++ 编写,响应迅速,性能好。但不支持数据库备份与恢复
一、新建连接
输入redis主机host,端口号port,再起个生动形象,简明达意的别名。
二、该工具支持根据筛选条件查询key,addnewkey,reload等。
三、支持常用redis操作
针对目标key执行rename,delete,addrow,reloadvalue操作。
四、命令控制台操作!
配置方法
配置 Redis DeskTop Manager
启动Redis服务端的时候会有默认端口6379,这里用默认端口配置连接。
配置如下:
1)定一个名称,随意
2)服务端地址,域名或ID,
3)Redis 端口,默认 6379
4)如果设置了连接密码,那么需要设置密码
配置好之后点击 Test Connection 按钮,看是否可以连接成功,如果失败请检查一下配置信息