数据类型的解析
- Redis键(key)
keys *
exists key 的名字
move key db 将key移动到另外一个DB钟
expire key 秒钟 设定key的存活时间
ttl key 查看key还剩下多少秒存活时间
type key 查看你的key值的类型 - Redis字符串操作
set/get/delete/append/strlen 赋值/获取键值/删除键/键值后面进行增加/键值长度
incr/decr/incrby/decrby 一定要数字进行加减
getrange/setrange
setex/setnx 设置key值和存活时间/ 没有这个key则设定
mset/mget/msetex 同时设置多个值 - Redis列表操作
头尾操作效率极高,中间元素进行操作效率低下
lpush/rpush/lrange
llen 列表长度
lpop/rpop 从左舍弃/从右舍弃
lindex 找索引所对应的值
lrem 次数 值 删除多次个这个值
lset key index value
linsert key before/after 值1 值2 key的值1前面/后面添加值2 - Redis集合
sadd/smembers/sismembers 添加/查看全部元素/判断某元素是否存在
scard 获取集合里面的元素个数
srem key value 删除集合中元素
srandmember key 数字 随机出几个元素
spop key 随机出栈
smove key1 key2 再key1的某个值 将key1中某个值赋值给key2
sdiff/ sinter/sunion 差集/交集/ 并集 - Redis哈希
hset/hget/hmset/hmget/hgetall/hdel
hlen
hexists key 在key里面某个值的’key’ — 两个key是不一样的
hkeys / hvals
hincrby/hincrbyfloat
hsetnv - Redis有序集合
zadd / zrange
zrangebyscore / zrevrangebyscore key score1 score2 输出成绩在score1到scrore2的key值
zrem key 成绩的key
解析配置文件 redis.conf
redis的持久化
- RDB (redis database)
在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲额Snapshot快照,它恢复时时将快照文件直接读到内存中。
redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程结束,再用这个临时文件替换上一次持久化好的文件,整个过程中,主进程不进行任何IO操作,这确保了极高的性能。
如果需要大规模数据恢复,且对于数据恢复的完整性不是非常敏感,那RDB比AOF更为高效,但是RDB的缺点在于最后一次持久化的数据可能丢失。
save “” 禁用
save 900 1 900秒1次改变
save 120 10 120秒有10次key改变
Stop-writes-on-basave-error no时表示不在乎数据不一致或者其他手段发现和控制 yes则相反
rdbcompression yes 采用LZF算法进行压缩,如果不想消耗CPU来进行压缩,则可以选择no
rdbchecksum yes在存储快照后,可以让Redis使用CRC64算法来进行数据校验,大约会有百分之10性能消耗. no则关闭
命令save或者bgsave都可以快速snapshot, bgsave异步, save则阻塞
适合大规模的数据恢复,对数据完整性和一致性要求不高 - AOF (Append only file)
appendonly yes则开启AOF
appendfilename 设置AOF文件的名称
appendfsync always/Everysec/No 同步持久化每次发生数据变更会立即记录到磁盘,性能差但是完整性好/ 出厂默认推荐,异步操作,每秒记录,有一秒内宕机,有数据丢失
No-appendfsync-on-rewrite 重写时是否运用appendfsync, 用默认no即可,保证数据安全性
Auto-aof-rewrite-min-size/Auto-aof-rewrite-percentage 设置重写的基准值
Redis 的事务(类似于转账, 一起成功或者一起失败)
- 可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其他命令插入,不许加塞
一个队列中,一次性、顺序性、排他性的执行一系列命令
DISCARD 取消事务,放弃执行事务块内的所有命令
EXEC 执行所有事务块内的命令
MULTI 标记一个事务块的开始
UNWATCH 取消WATCH命令对所有key的监控
WATCH 监视一个或者多个key(乐观锁)
MULTI后开启事务,然后事务入队列, 然后EXEC执行所有事务块
MULTI
set k1 v1
set k2 v2
set k3 v3
EXEC
再事务入队列时候执行DISCARD则放弃事务
开启WATCH , 当在EXEC事务执行之前, key的值被改动,则事务被打断
主从复制,读写分离
- 常用三种方式: 一主二仆、薪火相传、反客为主
更改slaveof , 只要从进行配置主的IP 端口号即可
(手动版)slaveof no one 反客为主, 使当前数据库停止与其他数据库的同步,转成主数据库
哨兵模式就是反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转为主库
redis目录下创建sentinel.conf, 输入 sentinel monitor 数据库名称 IP 端口号 票数
输入: reids-sentinel sentinel.conf即完成配置
一组sebtinel可以监控多个Master
复制原理:
slave启动成功连接到master后会发送一个sync命令
Master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,master将传送文件到slave,以完成一次完全同步
全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。
增量复制:Master继续将新的所有收集到的修改命令传给slave,以完成同步,但是只要是重新连接master,一次完全同步(全量复制)将被自动执行
复制延迟:
由于所有的写操作都是先在master上操作,然后同步到slave,所以从master同步到slave机器上有一定延迟,当系统繁忙时候,延迟问题会更严重,slave机器数量的增加也会使这个问题更加严重
Python中Redis的使用
import redis
import time
pool = redis.ConnectionPool(host='localhost', port=6379, db = 4)
conn = redis.Redis(connection_pool=pool)
'''
keys常用操作
'''
# conn.set('k8', 1)
# conn.set('k5', 1)
# print(conn.exists('k9'))
# print(conn.expire('k8', 10))
# print(conn.ttl('k8'))
# print(conn.move('k8', 1))
# print(conn.keys())
# print(conn.type('k5'))
'''
String操作
'''
# conn.set('string', '11')
# conn.set('string1', '1222323')
# print(conn.get('string'))
# # conn.delete('string1')
# print(conn.get('string1'))
# conn.append('string', 222)
# print(conn.get('string'))
# print(conn.strlen('string'))
# print(conn.incr('string'))
# print(conn.incrby('string', 10))
# print(conn.decr('string'))
# print(conn.decrby('string', 1000))
# print(conn.getrange('string1', 0, 3))
# conn.setrange('string1', 0, 'xxx')
# print(conn.get('string1'))
# print(conn.setnx('string2', '1'))
# print(conn.get('string2'))
# conn.setex('string3', 10, 'v4')
# print(conn.ttl('string3'))
# keydict = {}
# keydict['key1'] = 324
# keydict['key2'] = 'ag'
# print(conn.mset(keydict))
# print(conn.mget(['key1', 'k4']))
'''
Redis列表操作
'''
# conn.lpush('p',1,2,3,4,5)
# print(conn.lrange('p', 0, -1))
# conn.rpush('p2', 1, 2,3,4,5)
# print(conn.lrange('p2', 0, -1))
# print(conn.lpop('p'))
# print(conn.rpop('p2'))
# print(conn.llen('p'))
# print(conn.lindex('p', 10))
# print(conn.lindex('p', 11))
# print(conn.lrem('p', 2, 1))
# print(conn.lset('p', 1, 2))
# print(conn.linsert('p', 'after', 2, 'vdadada'))
# print(conn.lrange('p', 0, -1))
'''
Redis集合操作
'''
# conn.sadd('set01', 1, 2, 3, 1, 2, 4, 5, 6)
# print(conn.smembers('set01'))
# print(conn.sismember('set01', 5))
# conn.srem('set01', 1)
# print(conn.srandmember('set01', 4))
# print(conn.spop('set01'))
# print(conn.smove('set01', 'set02', 1))
# 差集、交集、并集
# print(conn.sdiff('set01', 'set02'))
# print(conn.sinter('set01', 'set02'))
# print(conn.sunion('set01', 'set02'))
'''
哈希操作
'''
# conn.hset('haxi01', 'key01', 1)
# conn.hset('haxi01', 'key02', '02')
# conn.hset('haxi01', 'key03', '03')
# conn.hset('haxi02', 'key02', '02')
# print(conn.hget('haxi01', 'key01'))
# conn.hmget('haxi01', 'key02', 'key03')
# print(conn.hget('haxi01', 'key02'))
# print(conn.hgetall('haxi01'))
# conn.hdel('haxi01', 'key03')
# print(conn.hlen('haxi01'))
# print(conn.hexists('haxi01', 'key03'))
# print(conn.hkeys('haxi01'))
# print(conn.hvals('haxi01'))
# print(conn.hincrby('haxi01', 'key01', 1))
# print(conn.hincrbyfloat('haxi01', 'key01', 0.5))
# print(conn.hsetnx('haxi01', 'key01', 5))
# print(conn.hsetnx('haxi01', 'key05', 5))
# print(conn.hlen('haxi01'))
'''
有序集合Zset
'''
# conn.zadd('zset01', {'key01': 50, 'key02':60, 'key03':70})
# print(conn.zrange('zset01', 0, -1))
# print(conn.zrange('zset01', 0, -1, withscores=True))
# print(conn.zrangebyscore('zset01', 60, 90))
# print(conn.zrem('zet01', 'key01'))
# print(conn.zrevrangebyscore('zset01', 80, 65))
'''
事务
'''
pipe = conn.pipeline()
pipe.watch('demo') #打开监控,监控某个key
conn.set('demo', 2)
key = 'demo'
pipe.set(key, 'demo_test_val')
print(pipe.execute())
pipe.get(key)
# val = pipe.execute()
val = conn.get(key)
print(val)
如果觉得我的文章对你有帮助,麻烦关注一下我的博客,我将会继续推出新的推文。