赞
踩
- redis的官网地址:
redis.io
- redis是一个高性能的key-value存储系统数据库。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型支持丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了主从同步
- Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。
总结一下Redis的特点:
接下来我们先在本地安装redis,下载地址:
https://download.csdn.net/download/qq_40558166/11965269
1.解压文件
2.配置环境变量
3.变成服务,进入安装目录下,地址栏cmd,然后输入命令
redis-server --service-install redis.windows.conf --loglevel verbose --maxheap 200m
4.启动服务
5.启动客户端和服务端命令
打开cmd,启动redis-server:服务器命令
redis-server redis.windows.conf
再打开cmd。启动redis-cli :客户端命令
redis-cli
注意:一个redis。windows.conf配置就是一个redis服务器,需要启动多个服务器时,只需要修改一下这个配置文件的名称redis.windows.conf,再用redis-server就可以启动
redis是一个高性能的key-value存储系统数据库。它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(有序集合)和hash(哈希类型)
类型 | 特点 | 使用场景 |
---|---|---|
string字符串 | key=value的形式,可存数字 | 定时持久化,常规计数 |
hash映射表 | string类型的key=value的映射表,适合存储对象 | 存储部分变更数据,比如用户信息表 |
list链表 | 有序可重复的链表 | |
set集合 | 无序不可重复的序列 | 常用交并差集,比如可以求共同关注的博主 |
zset有序集合 | 带score排名的无序不可重复序列 | 排行榜 |
命令 | 作用 |
---|---|
keys * | 返回键(key) |
keys list* | 返回名以list开头的所有键(key) |
exists list1 | 判断键名为list1的是否存在 存在返回1, 不存在返回0 |
del list1 | 删除一个键(名为list1) |
expire list1 10 | 设置键名为list1的过期时间为10秒后 |
ttl list1 | 查看键名为list1的过期时间,若为-1表示已过期 或 永不过期 |
move age 1 | 将键名age的转移到1数据库中 |
select 1 | /表示进入到1数据库中,默认在0数据库 |
persist age | 移除age的过期时间。 |
flushdb | 删除所有的数据 清除当前所在库的所有数据 |
flushall | 清空所有数据 |
命令 | 解释 |
---|---|
set age 1 | 添加键值age=1,存在则替换 |
get age | 获取age |
setnx age 2 | 添加不存在的age=2 |
setex age 5 3 | 添加有效期为5s的age=3 |
mset age 1 age2 1 | 添加多个age=1,age2=3 |
msetnx age 1 age2 3 | 添加多个不存在的age=1,age2=3 |
getset age 3 | 获取age以前的值,并设置为新值age=3 |
mget name age | 获取多个值name,age |
setrange name 5 hello | 设置name索引从5以后的值,类似name[5:]=‘hello’ |
getrange name 0 5 | 获取name[0:5] |
append name asasa | 在name后边追加asasa |
decr age | 对age-1 |
incr age | 对age+1 |
decyby age 10 | 对age-10 |
incrby age 8 | 对age+8 |
strlen name | 求age的长度 |
del name | 删除name |
type name | 返回name的数据类型 |
命令 | 解释 |
---|---|
hset user:001 name zs | 在user:001表中添加name=zs,有就替换 |
hget user:001 name | 获取user:001表中的name |
hsetnx user:001 age 5 | 在user:001表中设置不存在的age=5 |
hmset user:001 age 3 age2 5 | 在user:001表中添加age=3和age2=5 |
hmget user:001 age age2 | 在user:001表中获取age和age2 |
hdel user:001 age | 删除user:001表中的age |
hincrby user:001 age 5 | 在user:001表中对age+5 |
hdecrby user:001 age 3 | 在user:001表中对age—3 |
hkeys user:001 | 展示user:001表中的所有key |
hvals user:001 | 展示user:001表中的所有value |
hexists user:001 name | 判断user:001表中中是否存在name |
hlen user:001 age | 求user:001表中的长度 |
命令 | 解释 |
---|---|
lpush list 1 | 在list的头部添加元素1 |
rpush list 1 | 在list的尾部添加元素1 |
lpop list 1 | 在list的头部弹出元素 |
rpop list 1 | 在list的尾部弹出元素 |
rpoplpush list 1 list2 | 弹出list尾部的元素添加到list2的头部 |
lrange list 0 -1 | 展示出list[0:-1],也就是所有元素 |
lindex list 0 | 展示出list[0] |
ltrim list 0 2 | 删除其他元素,只剩下list[0:2] |
lset list 0 5 | list[0]=5 |
linsert list before a b | 在list元素a的前边添加b元素 |
llen list | list的长度 |
lrem list 0 a | 删除list中全部的a元素 |
lrem list 5 a | 从头开始搜索,删除list中5个a元素 |
lrem list -2 a | 从尾部开始搜索,删除list中 |
命令 | 解释 |
---|---|
sadd set 1 | 在set集合添加1 |
srem set 1 | 删除set中的1成员 |
spop set | 随机弹出一个成员 |
smember set | 展示set中的所有成员 |
smove set1 set2 5 | 将set1集合中的5成员,移动到set2中 |
srandmember set | 随机展示set中的一个成员 |
sismember set 5 | 判断5是不是set集合中的成员 |
scard set | set集合中的成员个数 |
sdiff set1 set2 | 差集,展示出set1-set2的差别成员 |
sdiffstore set set1 set2 | 将set1-set2的差别成员存到set3 |
sinter set1 set2 | 交集,展示出set1和set2的交集成员 |
sinterstore set set1 set2 | 将set1,set2的交集成员存到set3 |
sunion set1 set2 | 并集,展示出set1和set2的并集成员 |
sunionstore set set1 set2 | 将set1,set2的并集成员存到set3 |
命令 | 解释 |
---|---|
zadd zset 1 a | 在zset成员中添加分数为1的成员a |
zrange zset 0 -1 | 展示按分数从低到高排序后的zset[0:-1]的成员 |
zrange zset 0 -1 withscores | 展示按分数从低到高排序后的zset[0:-1]的成员,包括排名 |
zrevrange zset 0 -1 | 展示按分数从高到低排序后的zset[0:-1]的成员 |
zrevrange zset 0 -1 withscores | 展示按分数从高到低排序后的zset[0:-1]的成员,包括排名 |
zrangebyscore zset 4 5 withscores | 获取zset中分数[4:5]的成员,包括排名 |
zcount zset1 3 4 | 获取zset中分数[3:4]的成员数量 |
zrevrank zset a | 展示按分数从高到低的zset的a成员的索引 |
zrem zset a | 删除zset的a成员 |
zincrby zset 3 a | 对zset中的a成员的排名+3 |
zcard zset | zset的成员个数 |
zremrangebyrank zset1 1 2 | 删除zset索引在[1:2]之间的成员 |
zremrangebyscore zset1 3 4 | 删除zset分数在[3:4]之间的成员 |
数据库事务是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。
Redis支持简单的事务,下面我们来看一下Redis与 mysql事务的对比:
问题1:rollback与discard 的区别 :
如果已经成功执行了2条语句,第3条语句出错.Rollback后,前2条的语句影响消失.Discard只是结束本次事务,前2条语句造成的影响仍然还在。
问题2:在mutil后面的语句中, 语句出错可能有2种情况:
为了防止数据丢失以及服务重启时能够恢复数据,Redis支持数据的持久化,主要分为两种方式:RDB和AOF,redis默认采用的是RDB的方式。
RDB | AOF | |
---|---|---|
全名 | Redis DataBase | Append Only File |
简要 | RDB是将某一个时刻的内存快照,以二进制的方式写入磁盘的过程。 | AOF 可以把 Redis 每个键值对操作都记录到文件中。Redis 默认是关闭 AOF 持久化的。 |
优点 | RDB 的内容为二进制的数据,占用内存更小,更紧凑,更适合做为备份文件,因此可以更快的传输到远程服务器进行Redis 服务恢复; | ①AOF 持久化保存的数据更加完整,AOF 提供了三种保存策略:每次操作保存、每秒钟保存一次(默认)、跟随系统的持久化策略保存; ②AOF 采用的是命令追加的写入方式,所以不会出现文件损坏的问题,即使由于某些意外原因,导致了最后操作的持久化数据写入了一半,也可以通过 redis-check-aof 工具轻松的修复; ③AOF 持久化文件,非常容易理解和解析,它是把所有 Redis 键值操作命令,以文件的方式存入了磁盘。即使不小心使用 flushall 命令删除了所有键值信息,只要使用 AOF 文件,删除最后的 flushall 命令,重启 Redis 即可恢复之前误删的数据。 |
缺点 | ①RDB 只能保存某个时间间隔的数据,如果中途 Redis 服务被意外终止了,则会丢失一段时间内的 Redis 数据; ②RDB的时候数据集很大就会很耗时; | ① 对于相同的数据集来说,AOF 文件要大于 RDB 文件; ②在 Redis 负载比较高的情况下,RDB 比 AOF 性能更好; |
两种持久化机制的比较
RDB 和 AOF 持久化各有利弊,RDB 可能会导致一定时间内的数据丢失,而 AOF 由于文件较大则会影响 Redis 的启动速度,为了能同时使用 RDB 和 AOF 各种的优点,Redis 4.0 之后新增了混合持久化的方式。 在开启混合持久化的情况下,AOF 重写时会把 Redis 的持久化数据,以 RDB 的格式写入到 AOF 文件的开头,之后的数据再以 AOF 的格式化追加的文件的末尾。
混合持久化优点:
混合持久化缺点:
1.在dump rdb过程中,aof如果停止同步,会不会丢失?
答:不会,所有操作缓存在内存的队列里,dump完成后,统一操作。
2、aof重写是指什么?
答:由于日志保存的是所有操作命令,导致存的日志会过大,而且数据库中有可能数据进行过删除,因此日志中的一些命令就相当于无效,因此日志先会删除,然后内存中的数据会逆化成命令,再重新写入到日志文件中,以解决 aof日志过大的问。
3、如果rdb文件,和aof文件都存在,优先用谁来恢复数据?
答: 在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件完整。
4、恢复时rdb和aof哪个恢复的快
答: rdb快,因为其是数据的内存映射,直接载入到内存,而aof是命令,需要逐条执行
RDB的配置
Rdb快照的配置选项,在redis.windows.conf:
save 900 1 // 900内,有1条写入,则产生快照
save 300 1000 // 如果300秒内有1000次写入,则产生快照
save 60 10000 // 如果60秒内有10000次写入,则产生快照
(这3个选项都屏蔽,则rdb禁用)
和持久化相关的redis配置:
Aof 的配置:
第二种方案有一个好处:master宕机后,可以直接切换到slave1
步骤一:进入redis目录,先复制两个redis.windows.conf
步骤二:修改主机配置文件(禁用rdb,打开aof)
步骤三:配置两个从服务器(一台启用rdb,两台禁用aof,设置slave-of)
6380端口
6381端口
步骤四:进入redis目录下cmd,启动三台服务器
redis-server redis.windows.conf 默认启动
redis-server redis.windows6380.conf
redis-server redis.windows6381.conf
步骤五:启动客户端,再5库插入一条数据
步骤六:退出客户端,登录80端口看是否存在
redis客户端执行一条命令的过程:发送命令 >命令排队>命令执行>返回结果
使用python给redis发送命令时的过程:
当redis需要执行的命令较多时,这样的一来一回的网络传输所消耗的时间被称为RTT(Round Trip Time),显而易见,如果可以将这些命令作为一个请求一次性发送给服务端,并一次性将结果返回客户端,会节约很多网络传输的消耗,可以大大提升响应时间。因此我们通过pipeline来进行效率提升。
使用Pipeline执行速度比逐条执行要快,特别是客户端与服务端的网络延迟越大,性能体能越明显
原生批命令(mset, mget)与Pipeline对比
原生批命令是原子性,pipeline是非原子性
原生批命令一命令多个key, 但pipeline支持多命令(存在事务),非原子性
原生批命令是服务端实现,而pipeline需要服务端与客户端共同完成
安装redis模块:pip install redis
操作redis:
import redis
r1 = redis.Redis(host='localhost', port='6379', db=1, password='') # 连接方式1
r2 = redis.Redis(host='127.0.0.1', port=6379, db=8,password='') # 连接方式2
key='age'
print(redis.get(key))
使用pipeline
# coding:utf-8
import redis
r = redis.StrictRedis.from_url('redis://127.0.0.1/0')
# 创建管道对象
pipe = r.pipeline()
pipe.set('name', '张三')
pipe.set('age', 15)
pipe.set('gender', '男')
# 执行
pipe.execute()
连续执行pipeline
pipe.set('hello', 'redis').sadd('faz', 'baz').incr('num').execute()
接收批量值,返回类型为列表
with r.pipeline() as pipe:
for i in range(num_len):
pipe.rpop('num_list')
try:
result = pipe.execute()
print result
except Exception as e:
print e
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。