FaRM
所有服务器都在一个数据中心,但性能比Spanner高许多。
其中,有一个配置管理器,来决定每个数据分片中哪台服务器是primary,哪台是backup
通过ZooKeeper来帮助实现配置管理器。
每个数据分片对应了一个primary服务器和一个backup服务器,读取数据需要从primary处读取数据。
还有一台事务协调器
为了提高性能
- 数据分片,获得并行处理能力
- 将所有数据都存放在服务器的RAM中
- 使用NVRAM来解决RAM因供电故障导致数据丢失的情况
- 使用RDMA技术,即在不对服务器发出中断信号的情况下,通过网络接口卡(NIC)接收数据包并通过指令直接对服务器内存中的数据进行读写,即kernel bypass,在不涉及内核的情况下,应用层代码可以直接访问网络接口卡
非易失性RAM
为了避免因供电故障导致RAM中的数据丢失,在每个机架上都放了一个大电池,使得供电故障时电池系统会让服务器继续运行,但只有10min的时间,它会向所有服务器发送消息,服务器收到消息后,会停止所做的操作,将RAM中的数据复制到该服务器挂载的固态硬盘上,然后关机。如果遇上大范围的供电故障, 所有机器会将他们RAM中的数据保存在磁盘,当恢复后会自动重启来做恢复工作。
传统架构
不同服务器上应用程序的RPC数据包的交换
服务器发送RPC消息
位于用户态的应用程序通过调用内核中的系统调用来发送消息,通过socket层对数据进行缓存,涉及数据的拷贝,TCP协议栈负责处理关于重传、序列化等操作。
最底层为网卡(NIC)内核可以对它上面的寄存器进行通信和配置,通过电缆将bit信息发送到网络上的硬件。
在内核中存在网卡驱动,要做的便是通过网卡直接向主机内存读取和写入数据包或者访问并移动主机内存中的数据包。
队列存放着网卡通过DMA访问内存时所拿到的数据,等待内核来获取数据,还有一个对外发送数据的数据包队列。
另一台服务器收到数据后,会发送中断信号给内核,内核会驱动程序将数据包发送给TCP协议进行处理,写入buffer,应用程序会读取这些数据,并通过系统调用将内核buffer中的数据拷贝到用户态空间中去。
效率较低且消息传发速率远远小于电缆所能发送的速率。
FaRM提出的思路
- kernel bypass
- 对内核保护机制进行配置,使得让应用程序直接访问网卡。通过DMA可以直接访问应用程序内存,在不需要内核参与的情况下,应用程序可以直接看到那些到达的字节信息。当应用程序需要发送数据时,创建队列,网卡直接通过DMA来读取数据,并通过网线数据发送出去。
- RDMA:远程直接内存访问。是一种网卡。发送方可以通过RDMA系统发送特殊消息来告诉网卡直接对目标应用程序地址空间中的内存直接进行读写操作。
乐观锁并发控制
不需要加锁,直接去读取数据(one-sided RDMA读取),在使用乐观锁的情况下,不会直接写入数据,而是将他们先缓存到client事务本地,直到事务最终结束。当事务结束时,会尝试去提交事务,提交事务的过程中有一个验证执行顺序阶段,验证成功,就去提交事务,验证失败的话,终止并重新执行。