1、MySQL
将 innodb_flush_log_at_trx_commit 设置为1,保证每次事务的结束都会触发Log Thread 将log buffer中的数据写入文件并通知文件系统同步文件,从而保证不论是MySQL Crash 还是OS Crash,或者是主机断电都不会丢失任何已经提交的数据。
2、MongoDB
MongoDB的建议最小部署是一个复制集,包含3个数据节点。默认情况下应用的写操作(更新,插入或者删除)在主节点上完成后就会立即返回。写操作则通过OPLOG方式在后台异步方式复制到其他节点。在极端情况下,这些写操作可能还未在复制到从节点的时候主节点就出现宕机。这个时候发生主备节点切换,原主节点的写操作会被回滚到文件而对应用不可见(见备注1)。为防止这种情况出现,MongoDB建议对重要的数据使用 {w: “marjority”} 的选项。{w: “majority”} 可以保证数据在复制到多数节点后才返回成功结果。使用该机制可以有效防止数据回滚的发生。
另外你可以使用 {j:1} (可以和 w:”majrotiy” 结合使用) 来指定数据必须在写入WAL日志(write ahead log)之后才向应用返回成功确认。这个会导致写入性能有所下降,但是对于重要的数据可以考虑使用。
备注1:当secondary为primary后假设此时原先的primary被恢复了,启动之后成为了secondary节点,此时新的primary发现secondary有x数据而自己没有,那么此时就会出现数据回滚的情况,secondary会把x数据进行回滚到一个磁盘文件上(rollback_db_name),回头需要人工去处理,从用户角度出现这也是一种数据丢失的情况。
3、ES
写请求会在主分片和副本分片都成功后,才返回结果给客户端,从而保证数据在多个分片的一致性。
ES 每次调用 Lucene 的接口写入或删除数据后,都会将操作日志记录到 Translog 中防止意外断电或程序崩溃导致数据丢失。
Translog 的日志每次都会写入到操作系统的缓存中,只有执行 fsync 刷盘后才是安全的。Translog 的刷盘方式有两种:同步(request)和异步(async),ES 默认使用的是 request,即每次写入、更新、删除操作后立刻执行 fsync 落盘。
4、Cassandra
通过设定写一致性级别(Write Consistency Level)实现数据的写安全。
写操作的consistency level指定了写操作在通知客户端请求成功之前,必须确保已经成功完成写操作的replica的数量。
级别:ANY
写操作:
描述: 任意一个节点写操作已经成功。如果所有的replica节点都挂了,写操作还是可以在记录一个hinted handoff事件之后,返回成功。如果所有的replica节点都挂了,写入的数据,在挂掉的replica节点恢复之前,读不到。
用法:最小的延时等待,并且确保写请求不会失败。相对于其他级别提供最低的一致性和最高的可用性。
级别:ALL
读操作:
描述:向所有replica节点查询数据,返回所有的replica返回的数据中,timestamp最新的数据。如果某个replica节点没有响应,读操作会失败。
用法:相对于其他级别,提供最高的一致性和最低的可用性。 写操作: 描述:写操作必须将指定行的数据写到所有replica节点的commit log和memtable。 用法:相对于其他级别提供最高的一致性和最低的可用性。
级别:EACH_QUORUM
读操作:
描述:向每个数据中心内quorum数量的replica节点查询数据,返回时间戳最新的数据。
用法:同LOCAL_QUORUM
写操作:
描述:写操作必须将指定行的数据写到每个数据中心的quorum数量的replica节点的commit log和memtable。
用法:用于多数据中心集群严格的保证相同级别的一致性。例如,如果你希望,当一个数据中心挂掉了,或者不能满足quorum数量的replica节点写操作成功时,写请求返回失败。
级别:LOCAL_ONE
读操作:
描述:返回本地数据中心内离coordinator节点最近的replica节点的数据。
用法:同写操作Consistency level中该级别的用法。
写操作:
描述:任何一个本地数据中心内的replica节点写操作成功。
用法:对于多数据中心的情况,往往期望至少一个replica节点写成功,但是,又不希望有任何跨数据中心的通信。LOCAL_ONE正好能满足这样的需求。
级别:LOCAL_QUORUM
读操作:
描述:向每个数据中心内quorum数量的replica节点查询数据,返回时间戳最新的数据。避免跨数据中心的通信。
用法:使用SimpleStrategy时会失败。
写操作:
描述:本地数据中心内quorum数量的replica节点写操作成功。避免跨数据中心的通信。
用法:不能和SimpleStrategy一起使用。用于保证本地数据中心的数据一致性。
级别:LOCAL_SERIAL
读操作:
描述:同SERIAL,但是只限制为本地数据中心。
用法:同SERIAL。
写操作:
描述:本地数据中心内quorum数量的replica节点有条件地(conditionally)写成功。
用法:用于轻量级事务(lightweight transaction)下实现linearizable consistency,避免发生无条件的(unconditional)更新。
级别:ONE
读操作:
描述:返回由snitch决定的最近的replica返回的结果。默认情况下,后台会触发read repair确保其他replica的数据一致。
用法:提供最高级别的可用性,但是返回的结果不一定最新。
写操作:
描述:任意一个replica节点写操作已经成功,满足大多数用户的需求。
用法:一般离coordinator节点具体最近的replica节点优先执行。
级别:QUORUM
读操作:
描述:读取所有数据中心中quorum数量的节点的结果,返回合并后timestamp最新的结果。
用法:保证很强的一致性,虽然有可能读取失败。
级别:SERIAL
读操作:
描述:允许读取当前的(包括uncommitted的)数据,如果读的过程中发现uncommitted的事务,则commit它。
用法:轻量级事务。
级别:TWO
读操作:
描述:返回两个最近的replica的最新数据。
用法:和ONE类似。
级别:THREE
读操作:
描述:返回三个最近的replica的最新数据。
用法:和TWO类似。
5、Kafka
通过设置生产者的应答机制(acks)保证数据写入的安全:
- acks=0:代表producer往集群发送数据不需要等到集群的返回,不确保消息发送成功。安全性最低但是效 率最高。
- acks=1:代表producer往集群发送数据只要leader应答就可以发送下一条,只确保leader发送成功。
- acks=-1/acks=all:代表producer往集群发送数据需要所有的follower都完成从leader的同步才会发送下一条,确保 leader发送成功和所有的副本都完成备份。安全性最⾼高,但是效率最低。
6、RabbitMQ
镜像队列+publisher confirm/事务机制,保证消息写入的可靠性,但应该注意在事务机制下,生产消息的吞吐量会大幅下降。
7、RocketMQ
Master和Slave异步刷盘+Master、Slave同步复制,在尽量不降低写入性能的前提下,保证数据写入安全。
8、Redis
Redis由于主从之间是异步同步的,所以做不到100%的一致性要求。当客户端在 Redis 的主节点修改了数据后,立即返回,即使在主从网络断开的情况下,主节点依旧可以正常对外提供修改服务,所以 Redis 满足「可用性」。Redis 保证「最终一致性」,从节点会努力追赶主节点,最终从节点的状态会和主节点的状态将保持一致。如果网络断开了,主从节点的数据将会出现大量不一致,一旦网络恢复,从节点会采用多种策略努力追赶上落后的数据,继续尽力保持和主节点一致。假如主节点损坏无法启动,则未同步到从节点的数据将丢失。