安装
tar -zxf redis-3.2.3.tar.gz
cd redis-3.2.3
make
cd src && make install
便于管理
mkdir -p /usr/local/redis/bin
mkdir -p /usr/local/redis/etc
mv ./redis.conf /usr/local/redis/etc –移动配置文件
mv mkreleasehdr.sh redis-benchmark redis-check-aof redis-check-rdb redis-cli redis-sentinel redis-server redis-trib.rb /usr/local/redis/bin/ –移动src下的命令
启动redis服务端
/usr/local/redis/bin/redis-server
启动redis服务端–指定配置文件(将配置文件中daemonize no 改为daemonize yes,可后台启动)
/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf
检查启动状态
ps -ef|grep redis
netstat -tunpl | grep 6379
进入redis客户端
./redis-cli
停止redis
pkill redis-server
默认端口
6379
数据类型
string
设置值
set name liyanbin
setnx name liyanbin2 --若key存在,则返回0,原数据不更新(nx:not exists)
setex name 10 liyanbin3 --指定有效期,有效期过后key会被删除
setrange name 2 bin --name原为liyanbin,会将yan替换为bin,替换后为libinbin
mset name1 liyanbin1 name2 liyanbin2 name3 liyanbin3 --批量设置,若有一个失败则全部失败,返回0。对于mset,会覆盖已有的key,对于msetnx,若设置已有的key,会失败
获取值
get name
getset name new_liyanbin --设置key的值,并返回key的旧值。若没有旧值,返回nil
getrange name 0 1 --返回li,回去指定区间内的值
mget name name1 --获取多个key的值
自增
incr myNum --自增1
incrby mynum 6 --自增6
incrby mynum -6 --自减6
decr myNum --自减1
decr myNum 6 --自减6
若key不存在,默认为0
追加
append name _now --在name的值后面追加_now,返回新值得长度
获取长度
strlen name --获取name的长度
hash
设置值
hset user:001 name liyanbin --用于为哈希表中的字段赋值,如果哈希表不存在,一个新的哈希表被创建并进行 HSET 操作(返回值为1).如果字段已经存在于哈希表中,旧值将被覆盖(此时返回值为0)。
hsetnx user:001 name liyanbin --若key存在,则返回0,原数据不更新(nx:not exists)
hmset user:002 name1 liyanbin1 name2 liyanbin2 --批量设置
获取值
hget user:001 name
hmget user:002 name1 name2 --批量查询
自增
hincrby user:002 age 5
判断key是否存在
hexists user:002 name --存在返回1,不存在返回0
获取长度
hlen user:002 --返回哈希表中字段数量
删除
hdel user:002 name --删除
返回哈希表中所有key
hkeys user:001
返回哈希表中所有value
hvals user:001
返回哈希表中全部key和value
hgetall user:001
list--既可以作为栈(先进后出),也可以作为队列(先进先出)
设置值
lpush list1 liyanbin --从尾部压入一个元素(即python里面的append)(使用lrange取出时栈效果)
rpush list1 liyanbin2 --从头部压入一个元素(使用lrange取出时队列效果)
linsert list1 before one two --在one的上面插入一个two(栈底叫下面,栈顶叫上面)
lset list1 1 7 --从栈顶数的第二个值赋值为7
获取值
lrange list1 0 2 --获取后压入的三个值,栈,先进后出,所以取出的是后压入的
lrange list1 0 -1 ---取出0到-1的元素,及取出全部
删除值
lrem list5 2 a --从栈顶删除2个a
lrem list5 -2 a --从栈底删除两个a
lrem list5 0 a --删除全部a
ltrim list5 1 -1 --保留下标1到-1之间的数据,其他的删除
lpop list5 --从栈顶弹出元素,并返回元素
rpop list5 --从栈底弹出元素,并返回元素
rpoplpush list5 list6 --从list5栈底弹出元素并压入list6栈顶
lindex list5 0 --取出索引为0的位置元素的值
llen list5 --返回链表中元素个数
set---集合,元素是不重复的,无顺序
添加元素
sadd set1 liyanbin --向集合set1中添加一个元素
取出元素
smembers set1 --取出集合set1中的元素
删除元素
srem set1 liyanbin1
spop set1 --随机弹出一个元素并返回
sdiff set1 set2 --返回set1和set2的差集,即set1-set2
sdiffstore set3 set1 set2 --将set1和set2的差集存储到set3里面
sinter set1 set2 --返回交集
sinterstore set3 set1 set2 --将set1和set2的交集存储到set3里面
sunion set1 set2 --返回set1和set2的并集
sunionstore set3 set1 set2 --将set1和set2的并集存储到set3里面
smove set1 set2 liyanbin --将set1里面的liyanbin元素移动到set8里面
scard set1 --返回set1的元素个数
sismember set1 liyanbin --判断liyanbin是否是set1中的元素
srandmember set1 --随机返回set1中的一个元素,但不删除元素
zset--有序集合(sorted set)
添加
zadd set1 1 one --顺序号可以重复,值不能重复
取出元素
zrange zset1 0 -1 withscores --withscores输出顺序号
zrevrange zset1 0 -1 withscores --反向排序
zrangebyscore zset1 2 3 withscores --只取出score在2和3之间的
删除
zrem zset1 one
zremrangebyrank zset1 1 1 --删除索引在1到1之间的元素
zremrangebyscore zset1 1 1 --删除顺序号在1到1之间的元素
自增
zincrby zset1 2 one --如果one存在,则顺序号增加2,若one不存在,则创建one
zrank zset1 two --返回值是two的索引(不是顺序号)(排序方法是:第一个插入的索引号是0,第二个是1)
zrevrank zset1 two --返回值是two的索引(反过来排序)
zcount zset1 2 4 --返回顺序号在2和4之间的元素的数量
zcard zset1 --返回集合中所有元素的个数
配置文件
daemonize no 改为 daemonize yes ——后台启动
bind 127.0.0.1 –写成0.0.0.0,可监听所有网卡
键值命令
keys * --返回后面表达式匹配的所有键
exists name --确认键是否存在
del name --删除一个键
过期
expire name 10 --给name键设置10秒过期时间
ttl name --查看键还有多长时间过期,对于没有设置过期时间的键使用ttl,返回-1,对于使用的过期时间的键,过期后,ttl返回值为-2,原键被销毁
persist name --取消过期时间
数据库:
有16个数据库,编号为0-15,默认使用0数据库
select 0 --选择0号数据库
move name 1 --将name键从当前数据库移动到1号数据库
randomkey --随机返回一个键
rename name name_new --重命名一个键
typr name --返回键的数据类型
dbsize --返回当前数据库中key的数量
服务器命令
ping --若服务器正常连接,会返回PONG
info --获取服务器的一些信息
config get * --获取数据库配置信息
flushdb --删除当前数据库中所有key
flushall --删除所有数据库中所有key
安全性
requirepass 123456 –设置密码,配置文件修改后重启
./redis-cli -a 123456 –使用密码登录
主从复制
特点
master可以拥有多个slave
多个slave除了可以连接到master外,还可以连接到其他slave
主从复制不会阻塞master,在同步数据时,master还可以继续处理chient的请求
主从复制过程
slave与master建立连接,发送sync同步命令
master启动一个后台进程,将数据库快照保存在一个文件中,同时master主进程会收集新的写命令并缓存
后台保存完成后,将此文件发送给slave
slave将此文件保存在硬盘上
配置文件
slave配置文件:
slaveof 192.168.1.1 6379 --指定master的ip和端口
masterauth 123456 --登录master的密码
info可以查看自己的角色,连接状态等
事物处理
事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。
redis对事务的支持目前还比较简单。redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他client的命令。 由于redis是单线程来处理所有client的请求的所以做到这点是很容易的。一般情况下redis在接受到一个client发来的命令后会立即处理并 返回处理结果,但是当一个client在一个连接中发出multi命令有,这个连接会进入一个事务上下文,该连接后续的命令并不是立即执行,而是先放到一 个队列中。当从此连接受到exec命令后,redis会顺序的执行队列中的所有命令。并将所有命令的运行结果打包到一起返回给client.然后此连接就 结束事务上下文
举例
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set name liyanbin
QUEUED
127.0.0.1:6379> set name liyanbin2
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
127.0.0.1:6379> get name
"liyanbin2"
127.0.0.1:6379>
举例---当有一个操作失败后,不会影响其他成功的操作,即不会回滚整个事务
127.0.0.1:6379> set age 10
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr age
QUEUED
127.0.0.1:6379> incr name
QUEUED
127.0.0.1:6379> incr age
QUEUED
127.0.0.1:6379> exec
1) (integer) 11
2) (error) ERR value is not an integer or out of range
3) (integer) 12
127.0.0.1:6379>
举例---watch(乐观锁)后,若在执行事务前,watch的key有变化,则事务不会执行
session1
127.0.0.1:6379> watch name
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set name liyanbin3
QUEUED
127.0.0.1:6379> set age 20
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379>
session2
127.0.0.1:6379> set name test_liyanbin
OK
127.0.0.1:6379>
命令
1 DISCARD
取消事务,放弃执行事务块内的所有命令。
2 EXEC
执行所有事务块内的命令。
3 MULTI
标记一个事务块的开始。
4 UNWATCH
取消 WATCH 命令对所有 key 的监视。
5 WATCH key [key ...]
监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
持久化机制
snapshotting(快照方式,默认)
dump.rdb ---备份文件放在bin下的dump.rdb
save 900 1 --900秒内超过1个key被修改,则发起快照保存
save 300 10
save 60 10000
Append-only file(aof)
会将每一个写命令追加到文件中,redis重启时会依据文件重建数据库
appendonly yes --启用aof
# The name of the append only file (default: "appendonly.aof")
appendfilename "appendonly.aof" -----文件放在bin下的appendonly.aof
# appendfsync always --收到命令就写入磁盘,保证完全持久化,但是最慢
appendfsync everysec --每秒写入一次
# appendfsync no --完全依赖os,不保证持久化,性能比较好
python操作redis
库
pip install redis
---redis-py是Redis key-value 数据库的 Python 接口
pip install hiredis
---分析类提供了控制如何对 Redis 服务器的响应进行分析的途径。redis-py 提供了两个分析类, PythonParser和 HiredisParser。缺省情况下,如果安装了 hiredis 模块, redis-py 会尝试使用 HiredisParser,否则使用 PythonParser。
---Hiredis 是由 Redis 核心团队维护的 C 库。 Pieter Noordhuis 创建了 Python 的实现。分析 Redis 服务器的响应时,Hiredis 可以提供 10 倍的速度提升。性能提升在获取大量数据时优为明显,比如 LRANGE 和SMEMBERS 操作。
基本API
import redis
pool = redis.ConnectionPool(host='192.168.1.106', password='123456',port=6379, db=0)
r = redis.StrictRedis(connection_pool = pool) --使用连接池连接,不需要关闭连接
r.set('foo', 'bar')
r.get('foo')
语法:
StrictRedis 类试图遵守官方的命令语法,但也有几点例外:
1.SELECT:没有实现,Redis 客户端实例可以安全地在线程间共享。从内部实现来说,只有在命令执行时才获取连接实例,完成后直接返回连接池,命令永不修改客户端实例的状态。
但是,有一点需要注意:SELECT 命令。SELECT 命令允许切换当前连接使用的数据库。新的数据库保持被选中状态,直到选中另一个数据库或连接关闭。这会导致在返回连接池时,连接可能指定了别的数据库。
因此,redis-py 没有在客户端实例中实现 SELECT 命令。如果要在同一个应用中使用多个 Redis 数据库,应该给第一个数据库创建独立的客户端实例(可能也需要独立的连接池)。
在线程间传递 PubSub 和 Pipeline 对象是不安全的。
2.DEL:'del' 是 Python 语法的保留关键字。因此redis-py 使用 “delete” 代替
3.CONFIG GET|SET:分别用 config_get 和 config_set 实现
4.MULTI/EXEC:作为 Pipeline 类的一部分来实现。若在调用pipeline 方法时指定use_transaction=True,在执行 pipeline 时会用 MULTI 和 EXEC 封装 pipeline 的操作。参见下面 Pipeline 部分
5.SUBSCRIBE/LISTEN: 和 pipeline 类似,由于需要下层的连接保持状态, PubSub 也实现成单独的类。调用 Redis 客户端的 pubsub 方法返回一个 PubSub 的实例,通过这个实例可以订阅频道或侦听消息。两个类(StrictRedis 和 PubSub 类)都可以发布(PUBLISH)消息。
除了上面的改变,StrictRedis 的子类 Redis,提供了对旧版本 redis-py 的兼容:
LREM:参数 ‘num' 和 ‘value' 的顺序交换了一下,这样‘num' 可以提供缺省值 0.
ZADD:实现时 score 和 value 的顺序不小心弄反了,后来有人用了,就这样了
SETEX: time 和 value 的顺序反了
注:最好不要用 Redis,这个类只是做兼容用的