Redis 可用于内存存储,也可以基于持久化存储 Key-Value的形式存储。
Redis的数据结构
1.字符串(string)
2.字符串列表(lists)
3.字符串集合(sets)
4.有序字符串集合(sorted sets)
5.哈希(hashes)
String
使用INCR、DECR、DECRBY原子操作子操作试用场景:
在某种场景下有3个客户端同时读取了mynum的值(值为2),然后对其同时进行了加1的操作,那么,最后mynum的值一定是5。不少网站都利用redis的这个特性来实现业务上的统计计数需求。
Lists
lists中列表可以当做redis的数据结构,底层实现为链表,插入元素的效率高。lists的常用操作包括LPUSH、RPUSH、LRANGE等。我们可以用LPUSH在lists的左侧插入一个新元素,用RPUSH在lists的右侧插入一个新元素,用LRANGE命令从lists中指定一个范围来提取元素。
PHPresque的队列执行正是基于此实现消息队列
Sets
sets是一直无序的集合
常用操作smembers 集合名称 :列出集合中所有的元素
sismember 集合名称 元素:判断元素是否存在 1表示存在
sadd集合名称 元素:添加元素到集合中
Sorted sets也叫zets
sorted sets是一直有序的集合,集合中的每一个元素都与score(序号)相关联。
常用操作:zadd 集合名称 序号 元素 .添加
zrange集合名称 0 -1 with scores .列出所有元素
Hashes
存储为字符串与字符串值之间的映射
常用操作:创建hash HMSET hash名称 filed1 值 filed2 值
获取hash值 HGET hashset名称 field
Redis两种持久化存储方式AOF与RDB
RDB这种方式只需在redis.conf配置 save time key 在多长时间内改变多少建值就去在默认的dump.rdb存储一次,存储的路径名称、文件名称的详细配置都可在redis.conf进行配置。
RDB快照执行过程如下
1.Redis使用fork函数复制一份当前的进程(父进程)的副本(子进程)
2.父进程继续处理来自客户端的请求,子进程开始将内存中的数据写入硬盘中的临时文件。
3.当子进程写完所有的数据后,用该临时文件替换旧的RDB文件,一次快照完成。
通过SAVE或者BGSAVE进行快照,手动创建快照存储到rdb文件中。
AOF
AOF可以将Redis执行的每一条写命令追加到硬盘文件中,性能虽受到影响但是可以确保数据安全。
AOF默认是不开启的可以通过redis.conf文件 设置appendonly yes 开启AOF存储。
设置auto-aof-rewrite-percentage 100 目前文件超过上次重写的文件的百分之多少进行重写,如果没有重写则以文件大小为依据。
设置auto-aof-rewrite-min-size 64mb 当AOF文件的大小大于64MB进行重写
也可以手动执行命令BGREWRITEAOF进行重写
配置同步数据硬盘时:
# appendfsync always
appendfsync everysec
# appendfsync no
第一行表示每次AOF写入一个命令都会执行同步操作,这是最安全也是最慢的方式;
第二行表示每秒钟进行一次同步操作,一般来说使用这种方式已经足够;
第三行表示不主动进行同步操作,这是最不安全的方式。
复制
通过持久化功能,Redis保证了即使在服务器重启的情况下也不会损失(或少量损失)数据。但是由于数据是存储在一台服务器上的,如果这台服务器的硬盘出现故障,也会导致数据丢失。为了避免单点故障,我们希望将数据库复制多个副本以部署在不同的服务器上,即使有一台服务器出现故障其他服务器依然可以继续提供服务。这就要求当一台服务器上的数据库更新后,可以自动将更新的数据同步到其他服务器上,Redis提供了复制(replication)功能可以自动实现同步的过程。在此之前需要配置一下redis.conf中
bind 为当前的服务器的 IP
配置方法
-
通过配置文件 从数据库的配置文件中加入slaveof master-ip master-port
,主数据库无需配置
-
通过命令行参数 启动redis-server的时候,使用命令行参数--slaveof master-ip master port
SLAVEOF master-ip master-port
redis>SLAVEOF 127.0.0.1 6379
SLAVEOF NO ONE
可以是当前数据库停止接收其他数据库的同步,转成主数据库
- 配置只读模式
优点及应用场景
- 读写分离 通过复制可以实现读写分离以提高服务器的负载能力。在常见的场景中,读的频率大于写,当单机的Redis无法应付大量的读请求时(尤其是较耗资源的请求,比如SORT命令等)可以通过复制功能建立多个从数据库,主数据库只进行写操作,而从数据库负责读操作。
- 从数据库持久化
持久化通常相对比较耗时,为了提高性能,可以通过复制功能建立一个(或若干个)从数据库,并在从数据库中启用持久化,同时在主数据库禁用持久化。当从数据库崩溃时重启后主数据库会自动将数据同步过来,所以无需担心数据丢失。而当主数据库崩溃时,需要在从数据库中使用SLAVEOF
NO
ONE命令将从数据库提升成主数据库继续服务,并在原来的主数据库启动后使用SLAVEOF命令将其设置成新的主数据库的从数据库,即可将数据同步回来。
主从复制原理
众所周知,PHPResque是基于redis实现的,之前也讲到过队列的问题是基于Redis中列表的数据结构中实现的。首先不禁要问我们为什么要用resuqe,它能干什么?准确的说它也是为了提升服务器的性能,执行一些操作复杂、耗时、量大等工作。
流程:工作内容相同的我们要创建一个类,将不同的要操作的对象或者是参数传递到这个工作类当中去,一次执行这个队列中所有的任务,直到这个队列再也没有工作要去做。
应用的一些场景:
比如说在某一时间段内有大量下单为了更好的用户体验我要首先将下单结果反馈,然后我们要将其放置到队列当中去,当服务器真正空闲的时候(当然距离下单也不能太久),我们可以手动开启队列让其执行。这样就避免了某一时间段请求量过大导致服务器响应慢的问题。还有一些是比较耗时的操作,例如从服务器导出数据并且转换成运营需要的excel格式,如果说http直接请求这个操作的话,没等这些工作做完就直接返回超时。我们就可以考虑将其放入到队列当中去,这样这些工作可以在后台中运行很长时间。
在Yii2中需要安装yii2-resque组件 还需要yiisoft-redis组件
Yii::$app->resque->createJob(‘queue_name‘, ‘ClassWorker‘, $args = []);
创建延时工作:
$time = 1332067214;
Yii::$app->resque->enqueueJobAt($time, ‘queue_name‘, ‘ClassWorker‘, $args = []);
获取当前队列
Yii::$app->resque->getQueues();