在Redis中,用户可以通过执行SLAVEOF命令或者设置slaveof选项,让一个服务器去复制(replicate)另一个服务器,通常被复制的服务器被称为主服务器(master),而对主服务器进行复制的服务器则被称为从服务器(slave)。
Redis使用PSYNC命令来执行复制时的同步操作。PSYNC命令具有完整重同步(full resynchronization)和部分重同步(partial resynchronization)两种模式:
完整重同步用于处理初次复制情况:通过让主服务器创建并发送RDB文件,以及向从服务器发送保存在缓冲区里面的写命令来进行同步。
部分重同步则用于处理断线后重复制情况:当从服务器在断线后重新连接主服务器时,如果条件允许,主服务器可以将主从服务器连接断开期间执行的写命令发送给从服务器,从服务器只要接收并执行这些写命令,就可以将数据库更新至主服务器当前所处的状态。(其实主服务器和从服务器会分别维护一个复制偏移量,主从之间的复制会增加主从的偏移量值,通过偏移量值就能看出主从数据是否有差异。)
通过向从服务器发送SLAVEOF命令,可以让一个从服务器去复制一个主服务器,从服务器接收到SLAVEOF命令后:
1、设置主服务器的地址和端口
2、建立套接字连接
3、发送PING命令
4、身份验证
5、发送端口信息
6、同步,从服务器将向主服务器发送PSYNC命令,执行同步操作,并将自己的数据库更新至主服务器数据库当前所处的状态。
7、命令传播,当完成了同步之后,主从服务器就会进入命令传播阶段,这时主服务器只要一直将自己执行的写命令发送给从服务器,而从服务器只要一直接收并执行主服务器发来的写命令,就可以保证主从服务器一直保持一致了。
Redis有两种持久化方式,RDB和AOF。
RDB
该功能可以将某个时间点上的数据库状态保存到一个RDB文件中。RDB持久化功能所生成的RDB文件是一个经过压缩的二进制文件,通过该文件可以还原生成RDB文件时的数据库状态。服务器在载入RDB文件期间,会一直处于阻塞状态,直到载入工作完成为止。
RDB有手动触发和自动触发两种方式。手动触发可以使用bgsave命令,使用bgsave命令后,Redis会执行fork创建子进程完成RDB过程。自动触发则是需要配置save相关的配置,如“save m n”,表示m秒内数据集存在n次修改时,自动触发bgsave。
RDB的优缺点
优点:RDB是一个紧凑压缩的二进制文件,代表Redis在某个时间点上的数据快照,非常适合用于备份,全量复制等场景。比如每6小时执行bgsave备份,并将RDB文件拷贝到远程机器或者文件系统中,用于灾难恢复。Redis加载RDB恢复数据远远快于AOF方式。
缺点:没有办法做到实时持久化/秒级持久化。bgsave每次运行都要执行fork操作创建子进程,属于重量级操作,频繁执行成本过高。
另外值得一提的是,因为AOF文件的更新频率通常比RDB文件的更新频率高,所以:
如果服务器开启了AOF持久化功能,那么服务器会优先使用AOF文件来还原数据库状态。
只有在AOF持久化功能处于关闭状态时,服务器才会使用RDB文件来还原数据库状态。
当涉及到订单处理的场景时,责任链模式也是一种常见的设计模式。以下是一个关于责任链模式实际应用的例子:订单处理流程。在电子商务系统中,当客户下单后,订单需要经过一系列处理步骤,例如库存检查、支付验证、物流处理等。责任链模式可以用来处理这些不同的订单处理步骤。
首先,定义一个抽象处理器类AbstractOrderProcessor
作为处理器节点:
javapublic abstract class AbstractOrderProcessor {
protected AbstractOrderProcessor nextProcessor;
public void setNextProcessor(AbstractOrderProcessor nextProcessor) {
this.nextProcessor = nextProcessor;
}
public abstract void processOrder(Order order);
}
在上述代码中,AbstractOrderProcessor
类声明了一个指向下一个处理器的引用(nextProcessor
)。它还声明了一个processOrder()
方法,用于处理订单。具体的处理器类需要实现这个方法来执行实际的订单处理逻辑。
接下来,创建多个具体的处理器类,继承自AbstractOrderProcessor
:
使用 Snowflake 算法生成分布式 ID。Snowflake 算法是 Twitter 开源的一种简单而高效的分布式 ID 生成算法。它使用一个 64 位的整数来表示生成的 ID,其中包含以下几个部分:
时间戳:占用 42 位,精确到毫秒级别,可以使用当前时间减去一个起始时间戳来得到相对时间,然后将其转换为二进制表示。
工作机器 ID:占用 10 位,用于标识不同的工作机器。可以根据实际情况分配给每个工作机器一个唯一的 ID。
序列号:占用 12 位,用于解决在同一毫秒内产生多个 ID 的冲突问题。如果同一毫秒内生成的 ID 数量超过了序列号的范围,那么会等到下一毫秒再继续生成。