Redis
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
redis官网:http://redis.io/
本文采用最新版redis-3.2.0。
一、Redis的安装和基本使用
wget http://download.redis.io/releases/redis-3.2.0.tar.gz tar zxvf redis-3.2.0.tar.gz cd redis-3.2.0 make # 由于makefile文件已经写好,我们只需要直接在源码目录执行make命令进行编译即可:
启动服务端
src/redis-server
更多选项:
启动客户端
src/redis-cls 127.0.0.1:6379> keys * (empty list or set) 127.0.0.1:6379> set name flash OK 127.0.0.1:6379> get name "flash" 127.0.0.1:6379> set name alex ex 5 OK 127.0.0.1:6379> save # 数据持久化操作,重启后数据不会丢失 OK
更多选项:
src/redis-cli --help
redis配置文件详解:
# 指定redis只接收来自于哪个ip的请求,默认为127.0.0.1,表示只接收来自本机的请求 bind 192.168.65.245 # 保护模式 protected-mode yes # 默认端口,6379 port 6379 # 在高并发的环境中,为避免慢客户端的连接问题,需要设置一个高速后台日志 tcp-backlog 511 # 客户端连接超时时间 timeout 0 # 指定值用于发送ACKs的时间(秒) tcp-keepalive 0 daemonize no supervised no # 进程id文件位置 pidfile /var/run/redis.pid # 指定日志记录级别,生产环境推荐使用notice # redis总共支持四个级别:debug、verbose、notice、warning loglevel notice # 日志文件位置,默认为空 logfile "" # 可用数据库数,默认值16 databases 16 ######################快照###################### #保存数据到磁盘,格式如下 : # save <seconds> <changes> # 指出在多长时间内,有多少次更新操作,就将数据同步到数据文件 rdb 。 # 相当于条件触发抓取快照,这个可以多个条件配合 # 比如默认配置文件中的设置,就设置了三个条件 # save 900 1 900 秒内至少有 1 个 key 被改变 # save 300 10 300 秒内至少有 10 个 key 被改变 # save 60 10000 60 秒内至少有 10000 个 key 被改变 save 900 1 save 300 10 save 60 10000 # 后台存储错误停止写入 stop-writes-on-bgsave-error yes # 存储至本地数据时(持久化到rdb文件)是否压缩数据,默认为 yes rdbcompression yes # rdb文件是否直接 checksum rdbchecksum yes # 本地持久化数据库文件名,默认值为 dump.rdb dbfilename dump.rdb # 工作目录 dir ./ #######################复制################### # 主从复制 . 设置该数据库为其他数据库的从数据库 . # 设置当本机为 slav 服务时,设置 master 服务的 IP 地址及端口,在 Redis 启动时,它会自动从 master 进行数据同步 # slaveof <masterip><masterport> # 当 master 服务设置了密码保护时 ( 用 requirepass 制定的密码 ) # slave 服务连接 master 的密码 # masterauth <master-password> # 当从库同主机失去连接或者复制正在进行,从机库有两种运行方式: # 1) 如果 slave-serve-stale-data 设置为 yes( 默认设置 ) ,从库会继续响应客户端的请求 # 2) 如果 slave-serve-stale-data 是指为 no ,出去 INFO 和 SLAVOF 命令之外的任何请求都会返回一个 # 错误 "SYNC with master in progress" slave-serve-stale-data yes # 配置 slave 实例是否接受写。写 slave 对存储短暂数据(在同 master 数据同步后可以很容易地被删除)是有用的,但未配置的情况下,客户端写可能会发送问题。 # 从 Redis2.6 后,默认 slave 为 read-only slaveread-only yes # 从库会按照一个时间间隔向主库发送 PINGs. 可以通过 repl-ping-slave-period 设置这个时间间隔,默认是 10 秒 # repl-ping-slave-period 10 # repl-timeout 设置主库批量数据传输时间或者 ping 回复时间间隔,默认值是 60 秒 # 一定要确保 repl-timeout 大于 repl-ping-slave-period # repl-timeout 60 # 在 slave socket 的 SYNC 后禁用 TCP_NODELAY # 如果选择“ yes ” ,Redis 将使用一个较小的数字 TCP 数据包和更少的带宽将数据发送到 slave , 但是这可能导致数据发送到 slave 端会有延迟 , 如果是 Linux kernel 的默认配置,会达到 40 毫秒 . # 如果选择 "no" ,则发送数据到 slave 端的延迟会降低,但将使用更多的带宽用于复制 . repl-disable-tcp-nodelay no # 设置复制的后台日志大小。 # 复制的后台日志越大, slave 断开连接及后来可能执行部分复制花的时间就越长。 # 后台日志在至少有一个 slave 连接时,仅仅分配一次。 # repl-backlog-size 1mb # 在 master 不再连接 slave 后,后台日志将被释放。下面的配置定义从最后一个 slave 断开连接后需要释放的时间(秒)。 # 0 意味着从不释放后台日志 # repl-backlog-ttl 3600 # 如果 master 不能再正常工作,那么会在多个 slave 中,选择优先值最小的一个 slave 提升为 master ,优先值为 0 表示不能提升为 master 。 slave-priority 100 # 如果少于 N 个 slave 连接,且延迟时间 <=M 秒,则 master 可配置停止接受写操作。 # 例如需要至少 3 个 slave 连接,且延迟 <=10 秒的配置: # min-slaves-to-write 3 # min-slaves-max-lag 10 # 设置 0 为禁用 # 默认 min-slaves-to-write 为 0 (禁用), min-slaves-max-lag 为 10 #################### 安全 ############ # 设置客户端连接后进行任何其他指定前需要使用的密码。 # 警告:因为 redis 速度相当快,所以在一台比较好的服务器下,一个外部的用户可以在一秒钟进行 150K 次的密码尝试,这意味着你需要指定非常非常强大的密码来防止暴力破解 # requirepass foobared # 命令重命名 . # 在一个共享环境下可以重命名相对危险的命令。比如把 CONFIG 重名为一个不容易猜测的字符。 # 举例 : # rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52 # 如果想删除一个命令,直接把它重命名为一个空字符 "" 即可,如下: # rename-command CONFIG "" ################################### 约束################################### #设置同一时间最大客户端连接数,默认无限制, #Redis 可以同时打开的客户端连接数为 Redis 进程可以打开的最大文件描述符数, #如果设置 maxclients 0 ,表示不作限制。 #当客户端连接数到达限制时, Redis 会关闭新的连接并向客户端返回 max number of clients reached 错误信息 # maxclients 10000 # 指定 Redis 最大内存限制, Redis 在启动时会把数据加载到内存中,达到最大内存后, Redis 会按照清除策略尝试清除已到期的 Key # 如果 Redis 依照策略清除后无法提供足够空间,或者策略设置为 ”noeviction” ,则使用更多空间的命令将会报错,例如 SET, LPUSH 等。但仍然可以进行读取操作 # 注意: Redis 新的 vm 机制,会把 Key 存放内存, Value 会存放在 swap 区 # 该选项对 LRU 策略很有用。 # maxmemory 的设置比较适合于把 redis 当作于类似 memcached 的缓存来使用,而不适合当做一个真实的 DB 。 # 当把 Redis 当做一个真实的数据库使用的时候,内存使用将是一个很大的开销 # maxmemory <bytes> # 当内存达到最大值的时候 Redis 会选择删除哪些数据?有五种方式可供选择 # volatile-lru -> 利用 LRU 算法移除设置过过期时间的 key (LRU: 最近使用 Least RecentlyUsed ) # allkeys-lru -> 利用 LRU 算法移除任何 key # volatile-random -> 移除设置过过期时间的随机 key # allkeys->random -> remove a randomkey, any key # volatile-ttl -> 移除即将过期的 key(minor TTL) # noeviction -> 不移除任何可以,只是返回一个写错误 # 注意:对于上面的策略,如果没有合适的 key 可以移除,当写的时候 Redis 会返回一个错误 # 默认是 : volatile-lru # maxmemory-policy volatile-lru # LRU 和 minimal TTL 算法都不是精准的算法,但是相对精确的算法 ( 为了节省内存 ) ,随意你可以选择样本大小进行检测。 # Redis 默认的灰选择 3 个样本进行检测,你可以通过 maxmemory-samples 进行设置 # maxmemory-samples 3 ############################## AOF############################### # 默认情况下, redis 会在后台异步的把数据库镜像备份到磁盘,但是该备份是非常耗时的,而且备份也不能很频繁,如果发生诸如拉闸限电、拔插头等状况,那么将造成比较大范围的数据丢失。 # 所以 redis 提供了另外一种更加高效的数据库备份及灾难恢复方式。 # 开启 append only 模式之后, redis 会把所接收到的每一次写操作请求都追加到 appendonly.aof 文件中,当 redis 重新启动时,会从该文件恢复出之前的状态。 # 但是这样会造成 appendonly.aof 文件过大,所以 redis 还支持了 BGREWRITEAOF 指令,对 appendonly.aof 进行重新整理。 # 你可以同时开启 asynchronous dumps 和 AOF appendonly no # AOF 文件名称 ( 默认 : "appendonly.aof") # appendfilename appendonly.aof # Redis 支持三种同步 AOF 文件的策略 : # no: 不进行同步,系统去操作 . Faster. # always: always 表示每次有写操作都进行同步 . Slow, Safest. # everysec: 表示对写操作进行累积,每秒同步一次 . Compromise. # 默认是 "everysec" ,按照速度和安全折中这是最好的。 # 如果想让 Redis 能更高效的运行,你也可以设置为 "no" ,让操作系统决定什么时候去执行 # 或者相反想让数据更安全你也可以设置为 "always" # 如果不确定就用 "everysec". # appendfsync always appendfsync everysec # appendfsync no # AOF 策略设置为 always 或者 everysec 时,后台处理进程 ( 后台保存或者 AOF 日志重写 ) 会执行大量的 I/O 操作 # 在某些 Linux 配置中会阻止过长的 fsync() 请求。注意现在没有任何修复,即使 fsync 在另外一个线程进行处理 # 为了减缓这个问题,可以设置下面这个参数 no-appendfsync-on-rewrite no-appendfsync-on-rewrite no # AOF 自动重写 # 当 AOF 文件增长到一定大小的时候 Redis 能够调用 BGREWRITEAOF 对日志文件进行重写 # 它是这样工作的: Redis 会记住上次进行些日志后文件的大小 ( 如果从开机以来还没进行过重写,那日子大小在开机的时候确定 ) # 基础大小会同现在的大小进行比较。如果现在的大小比基础大小大制定的百分比,重写功能将启动 # 同时需要指定一个最小大小用于 AOF 重写,这个用于阻止即使文件很小但是增长幅度很大也去重写 AOF 文件的情况 # 设置 percentage 为 0 就关闭这个特性 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb ################################ LUASCRIPTING ############################# # 一个 Lua 脚本最长的执行时间为 5000 毫秒( 5 秒),如果为 0 或负数表示无限执行时间。 lua-time-limit 5000 ################################LOW LOG################################ # Redis Slow Log 记录超过特定执行时间的命令。执行时间不包括 I/O 计算比如连接客户端,返回结果等,只是命令执行时间 # 可以通过两个参数设置 slow log :一个是告诉 Redis 执行超过多少时间被记录的参数 slowlog-log-slower-than( 微妙 ) , # 另一个是 slow log 的长度。当一个新命令被记录的时候最早的命令将被从队列中移除 # 下面的时间以微妙为单位,因此 1000000 代表一秒。 # 注意指定一个负数将关闭慢日志,而设置为 0 将强制每个命令都会记录 slowlog-log-slower-than 10000 # 对日志长度没有限制,只是要注意它会消耗内存 # 可以通过 SLOWLOG RESET 回收被慢日志消耗的内存 # 推荐使用默认值 128 ,当慢日志超过 128 时,最先进入队列的记录会被踢出 slowlog-max-len 128 ################################ 事件通知 ############################# # 当事件发生时, Redis 可以通知 Pub/Sub 客户端。 # 可以在下表中选择 Redis 要通知的事件类型。事件类型由单个字符来标识: # K Keyspace 事件,以 _keyspace@<db>_ 的前缀方式发布 # E Keyevent 事件,以 _keysevent@<db>_ 的前缀方式发布 # g 通用事件(不指定类型),像 DEL, EXPIRE, RENAME, … # $ String 命令 # s Set 命令 # h Hash 命令 # z 有序集合命令 # x 过期事件(每次 key 过期时生成) # e 清除事件(当 key 在内存被清除时生成) # A g$lshzxe 的别称,因此 ”AKE” 意味着所有的事件 # notify-keyspace-events 带一个由 0 到多个字符组成的字符串参数。空字符串意思是通知被禁用。 # 例子:启用 list 和通用事件: # notify-keyspace-events Elg # 默认所用的通知被禁用,因为用户通常不需要改特性,并且该特性会有性能损耗。 # 注意如果你不指定至少 K 或 E 之一,不会发送任何事件。 notify-keyspace-events “” ############################## 高级配置 ############################### # 当 hash 中包含超过指定元素个数并且最大的元素没有超过临界时, # hash 将以一种特殊的编码方式(大大减少内存使用)来存储,这里可以设置这两个临界值 # Redis Hash 对应 Value 内部实际就是一个 HashMap ,实际这里会有 2 种不同实现, # 这个 Hash 的成员比较少时 Redis 为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的 HashMap 结构,对应的 valueredisObject 的 encoding 为 zipmap, # 当成员数量增大时会自动转成真正的 HashMap, 此时 encoding 为 ht 。 hash-max-zipmap-entries 512 hash-max-zipmap-value 64 # 和 Hash 一样,多个小的 list 以特定的方式编码来节省空间。 # list 数据类型节点值大小小于多少字节会采用紧凑存储格式。 list-max-ziplist-entries 512 list-max-ziplist-value 64 # set 数据类型内部数据如果全部是数值型,且包含多少节点以下会采用紧凑格式存储。 set-max-intset-entries 512 # 和 hashe 和 list 一样 , 排序的 set 在指定的长度内以指定编码方式存储以节省空间 # zsort 数据类型节点值大小小于多少字节会采用紧凑存储格式。 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 # Redis 将在每 100 毫秒时使用 1 毫秒的 CPU 时间来对 redis 的 hash 表进行重新 hash ,可以降低内存的使用 # 当你的使用场景中,有非常严格的实时性需要,不能够接受 Redis 时不时的对请求有 2 毫秒的延迟的话,把这项配置为 no 。 # 如果没有这么严格的实时性要求,可以设置为 yes ,以便能够尽可能快的释放内存 activerehashing yes # 客户端的输出缓冲区的限制,因为某种原因客户端从服务器读取数据的速度不够快, # 可用于强制断开连接(一个常见的原因是一个发布 / 订阅客户端消费消息的速度无法赶上生产它们的速度)。 # 可以三种不同客户端的方式进行设置: # normal -> 正常客户端 # slave -> slave 和 MONITOR 客户端 # pubsub -> 至少订阅了一个 pubsub channel 或 pattern 的客户端 # 每个 client-output-buffer-limit 语法 : # client-output-buffer-limit <class><hard limit> <soft limit> <soft seconds> # 一旦达到硬限制客户端会立即断开,或者达到软限制并保持达成的指定秒数(连续)。 # 例如,如果硬限制为 32 兆字节和软限制为 16 兆字节 /10 秒,客户端将会立即断开 # 如果输出缓冲区的大小达到 32 兆字节,客户端达到 16 兆字节和连续超过了限制 10 秒,也将断开连接。 # 默认 normal 客户端不做限制,因为他们在一个请求后未要求时(以推的方式)不接收数据, # 只有异步客户端可能会出现请求数据的速度比它可以读取的速度快的场景。 # 把硬限制和软限制都设置为 0 来禁用该特性 client-output-buffer-limit normal 0 0 0 client-output-buffer-limit slave 256mb 64mb60 client-output-buffer-limit pubsub 32mb 8mb60 # Redis 调用内部函数来执行许多后台任务,如关闭客户端超时的连接,清除过期的 Key ,等等。 # 不是所有的任务都以相同的频率执行,但 Redis 依照指定的“ Hz ”值来执行检查任务。 # 默认情况下,“ Hz ”的被设定为 10 。 # 提高该值将在 Redis 空闲时使用更多的 CPU 时,但同时当有多个 key 同时到期会使 Redis 的反应更灵敏,以及超时可以更精确地处理。 # 范围是 1 到 500 之间,但是值超过 100 通常不是一个好主意。 # 大多数用户应该使用 10 这个预设值,只有在非常低的延迟的情况下有必要提高最大到 100 。 hz 10 # 当一个子节点重写 AOF 文件时,如果启用下面的选项,则文件每生成 32M 数据进行同步。 aof-rewrite-incremental-fsync yes
二、使用Redis启动脚本设置开机自启动
启动脚本
推荐在生产环境中使用启动脚本方式启动redis服务。启动脚本 redis_init_script
位于位于Redis的 /utils/
目录下。
#大致浏览下该启动脚本,发现redis习惯性用监听的端口名作为配置文件等命名,我们后面也遵循这个约定。
#redis服务器监听的端口
REDISPORT=6379
#服务端所处位置,在make install后默认存放与`/usr/local/bin/redis-server`,如果未make install则需要修改该路径,下同。
EXEC=/usr/local/bin/redis-server
#客户端位置
CLIEXEC=/usr/local/bin/redis-cli
#Redis的PID文件位置
PIDFILE=/var/run/redis_${REDISPORT}.pid
#配置文件位置,需要修改
CONF="/etc/redis/${REDISPORT}.conf"
配置环境
1. 根据启动脚本要求,将修改好的配置文件以端口为名复制一份到指定目录。需使用root用户。
mkdir /etc/redis cp redis.conf /etc/redis/6379.conf
vim /etc/redis/6379.conf
daemonize yes;
2. 将启动脚本复制到/etc/init.d目录下,本例将启动脚本命名为redisd(通常都以d结尾表示是后台自启动服务)。
cp redis_init_script /etc/init.d/redisd
3. 设置为开机自启动
此处直接配置开启自启动 chkconfig redisd on
将报错误: service redisd does not support chkconfig
参照 此篇文章 ,在启动脚本开头添加如下两行注释以修改其运行级别:
#!/bin/sh
# chkconfig: 2345 90 10
# description: Redis is a persistent key-value database
#
再设置即可成功。
#设置为开机自启动服务器 chkconfig redisd on #打开服务 service redisd start #关闭服务 service redisd stop
二、Python操作Redis
安装redis模块:pip3 install redis
API的使用
1、连接模式
import redis r = redis.Redis(host='192.168.65.245', port=6379) # print(r.keys()) print(r.get('name')) r.set("foo", 'whatever') print(str(r.get('foo'), 'utf8'))
2、连接池
import redis pool = redis.ConnectionPool(host='192.168.65.245', port=6379)
r = redis.Redis(connection_pool=pool) r.set('foo', 'Bar') print(str(r.get('foo'), 'utf8'))
3、操作
String操作,redis中的String在内存中按照一个name对应一个value来存储。如图:
set(name, value, ex=None, px=None, nx=False, xx=False)
在Redis中设置值,默认,不存在则创建,存在则修改 参数: ex,过期时间(秒) px,过期时间(毫秒) nx,如果设置为True,则只有name不存在时,当前set操作才执行 xx,如果设置为True,则只有name存在时,当前set操作才执行
setnx(name,value) 相当于 set(name,value,nx=True)
setex(name,value) 相当于 set(name,value,ex=value)
psetex(name, time_ms, value) 相当于 set(name,value,px=value)
mset(*args, **kwargs)
批量设置值 如: mset(k1='v1', k2='v2') 或 mget({'k1': 'v1', 'k2': 'v2'})
r.mset(k1='v1', k2='v2')
print(r.mget('k1','k2'))
getset(name, value)
设置新值并获取原来的值 print(r.getset("name", 'flash')) print(r.get('name')) # 输出结果: b'abc' b'flash'
getrange(key, start, end)
# 获取子序列(根据字节获取,非字符) # 参数: # name,Redis 的 name # start,起始位置(字节) # end,结束位置(字节) 类似切片 r.set('num', '123456') print(r.getrange('num', 2, 4)) # 输出结果:b'345'
setrange(name, offset, value)
修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后添加) # 参数: # offset,字符串的索引,字节(一个汉字三个字节) # value,要设置的值 r.set('num', '123456') r.setrange('num', 3, "AAA") print(r.getrange('num', 1, 5)) # 输出结果:b'23AAA'
setbit(name, offset, value) ps:可用于获取网站UV
# 对name对应值的二进制表示的位进行操作 # 参数: # name,redis的name # offset,位的索引(将值变换成二进制后再进行索引) # value,值只能是 1 或 0 import redis pool = redis.ConnectionPool(host='192.168.65.245', port=6379) r = redis.Redis(connection_pool=pool) r.setbit('uv_count', 5, 1) r.setbit('uv_count', 8, 1) r.setbit('uv_count', 3, 1) r.setbit('uv_count', 3, 1) print("uv_count:", r.bitcount('uv_count')) # bitcount获取name对应的值的二进制表示中 1 的个数
n = '371' r.set('t', n) for i in n: print(i, ord(i), bin(ord(i))) # ord(i) 获取ASCII值, bin(ord(i))获取二进制值 r.setbit('t', 5, 1) print("res:", r.get('t'))
# 输出结果:
uv_count: 4
3 51 0b110011
7 55 0b110111
1 49 0b110001
res: b'771'
ps: 我们可以根据用户id来统计网站UV,上面的代码第四行中的5表示当用户的id为5,则将第5位设置为1,8、3类似。
bitop(operation, dest, *keys)
# 获取多个值,并将值做位运算,将最后的结果保存至新的name对应的值 # 参数: # operation,AND(并) 、 OR(或) 、 NOT(非) 、 XOR(异或) # dest, 新的Redis的name # *keys,要查找的Redis的name # 如: bitop("AND", 'new_name', 'n1', 'n2', 'n3') # 获取Redis中n1,n2,n3对应的值,然后讲所有的值做位运算(求并集),然后将结果保存 new_name 对应的值中
strlen(name)
# 返回name对应值的字节长度(一个汉字3个字节)
incr(self, name, amount=1)
# 自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。 # 参数: # name,Redis的name # amount,自增数(必须是整数) # 注:同incrby
incrbyfloat(self, name, amount=1.0)
# 自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。 # 参数: # name,Redis的name # amount,自增数(浮点型)
decr(self, name, amount=1)
# 自减 name对应的值,当name不存在时,则创建name=amount,否则,则自减。 # 参数: # name,Redis的name # amount,自减数(整数)
append(key, value)
# 在redis name对应的值后面追加内容 # 参数: key, redis的name value, 要追加的字符串 print(r.get('name')) # 输出结果: flash print(r.append('name', '666')) # 输出结果:flash666
Hash操作,redis中Hash在内存中的存储格式如下图:
hset(name, key, value)
# name对应的hash中设置一个键值对(不存在,则创建;否则,修改) # 参数: # name,redis的name # key,name对应的hash中的key # value,name对应的hash中的value # 注: # hsetnx(name, key, value),当name对应的hash中不存在当前key时则创建(相当于添加)
hmset(name, mapping)
# 在name对应的hash中批量设置键值对 # 参数: # name,redis的name # mapping,字典,如:{'k1':'v1', 'k2': 'v2'} # 如: # r.hmset('xx', {'k1':'v1', 'k2': 'v2'})
hget(name,key)
# 在name对应的hash中获取根据key获取value
hmget(name, keys, *args)
# 在name对应的hash中获取多个key的值 # 参数: # name,reids对应的name # keys,要获取key集合,如:['k1', 'k2', 'k3'] # *args,要获取的key,如:k1,k2,k3 # 如: # r.mget('xx', ['k1', 'k2']) # 或 # print r.hmget('xx', 'k1', 'k2')
hgetall(name)
获取name对应hash的所有键值
hlen(name)
# 获取name对应的hash中键值对的个数
hkeys(name)
# 获取name对应的hash中所有的key的值
hvals(name)
# 获取name对应的hash中所有的value的值
hexists(name, key)
# 检查name对应的hash是否存在当前传入的key
hdel(name,*keys)
# 将name对应的hash中指定key的键值对删除
hincrby(name, key, amount=1)
# 自增name对应的hash中的指定key的值,不存在则创建key=amount # 参数: # name,redis中的name # key, hash对应的key # amount,自增数(整数)
hincrbyfloat(name, key, amount=1.0)
# 自增name对应的hash中的指定key的值,不存在则创建key=amount # 参数: # name,redis中的name # key, hash对应的key # amount,自增数(浮点数) # 自增name对应的hash中的指定key的值,不存在则创建key=amount
hscan(name, cursor=0, match=None, count=None)
# 增量式迭代获取,对于数据大的数据非常有用,hscan可以实现分片的获取数据,并非一次性将数据全部获取完,从而放置内存被撑爆 # 参数: # name,redis的name # cursor,游标(基于游标分批取获取数据) # match,匹配指定key,默认None 表示所有的key # count,每次分片最少获取个数,默认None表示采用Redis的默认分片个数 # 如: # 第一次:cursor1, data1 = r.hscan('xx', cursor=0, match=None, count=None) # 第二次:cursor2, data1 = r.hscan('xx', cursor=cursor1, match=None, count=None) # ... # 直到返回值cursor的值为0时,表示数据已经通过分片获取完毕
hscan_iter(name, match=None, count=None)
# 利用yield封装hscan创建生成器,实现分批去redis中获取数据 # 参数: # match,匹配指定key,默认None 表示所有的key # count,每次分片最少获取个数,默认None表示采用Redis的默认分片个数 # 如: # for item in r.hscan_iter('xx'): # print item
List操作,redis中的List在在内存中按照一个name对应一个List来存储。如图:
lpush(name,values)
# 在name对应的list中添加元素,每个新的元素都添加到列表的最左边 # 如: # r.lpush('oo', 11,22,33) # 保存顺序为: 33,22,11 # 扩展: # rpush(name, values) 表示从右向左操作
三、Redis发布与订阅
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import redis 5 6 7 class RedisHelper(object): 8 9 def __init__(self): 10 self.__conn = redis.Redis(host='192.168.65.245') 11 self.chan_sub = 'fm104.5' # 订阅104.5频道 12 self.chan_pub = 'fm87.7' # 发布87.7频道 13 14 def public(self, msg): 15 self.__conn.publish(self.chan_pub, msg) # 发布消息 16 return True 17 18 def subscribe(self): 19 pub = self.__conn.pubsub() # 打开 收音机 20 pub.subscribe(self.chan_sub) # 拧到 哪个台 21 pub.parse_response() # 准备监听消息 22 return pub
发布者:
1 import redis 2 3 r = redis.Redis(host='192.168.65.245') 4 r.publish("fm104.5", 'hello')
订阅者:
1 import redis 2 3 class RedisHelper(object): 4 5 def __init__(self): 6 self.__conn = redis.Redis(host='192.168.65.245') 7 self.chan_sub = 'fm104.5' # 订阅104.5频道 8 9 10 def subscribe(self): 11 pub = self.__conn.pubsub() # 打开 收音机 12 pub.subscribe(self.chan_sub) # 拧到 哪个台 13 pub.parse_response() # 准备监听消息 14 return pub 15 16 obj = RedisHelper() 17 redis_sub = obj.subscribe() 18 19 20 while True: 21 msg = redis_sub.parse_response() 22 print(msg)