6.3. write-behind 缓存存储
write-behind 是一个缓存写入模式,对内存的写入是同步的,对缓存存储的写入是异步的。
当客户端发送写入请求时,Data Grid 会将这些操作添加到修改队列中。Data Grid 在它们加入队列时处理操作,因此调用线程不会被阻止,操作会立即完成。
如果修改队列中的写入操作数量超过队列的大小,Data Grid 会将这些额外的操作添加到队列中。但是,在 Data Grid 进程已在队列中已有的操作之前,这些操作才会完成。
例如,调用 Cache.putAsync
可立即返回,如果修改队列未满,Stage 也会立即完成。如果修改队列已满,或者 Data Grid 当前正在处理一系列写入操作,则 Cache.putAsync
立即返回,Stage 则完成。
write-behind 模式比直写模式提供了性能优势,因为缓存操作不需要等待对底层缓存存储的更新完成。但是,缓存存储中的数据会与缓存中的数据不一致,直到处理修改队列为止。因此,write-behind 模式适用于具有低延迟的缓存存储,如未共享和基于文件的缓存存储,其中写入缓存的时间和对缓存存储的写入是尽可能小的。
write-behind 配置
XML
<distributed-cache> <persistence> <table-jdbc-store xmlns="urn:infinispan:config:store:sql:15.0" dialect="H2" shared="true" table-name="books"> <connection-pool connection-url="jdbc:h2:mem:infinispan" username="sa" password="changeme" driver="org.h2.Driver"/> <write-behind modification-queue-size="2048" fail-silently="true"/> </table-jdbc-store> </persistence> </distributed-cache>
JSON
{ "distributed-cache": { "persistence" : { "table-jdbc-store": { "dialect": "H2", "shared": "true", "table-name": "books", "connection-pool": { "connection-url": "jdbc:h2:mem:infinispan", "driver": "org.h2.Driver", "username": "sa", "password": "changeme" }, "write-behind" : { "modification-queue-size" : "2048", "fail-silently" : true } } } } }
YAML
distributedCache: persistence: tableJdbcStore: dialect: "H2" shared: "true" tableName: "books" connectionPool: connectionUrl: "jdbc:h2:mem:infinispan" driver: "org.h2.Driver" username: "sa" password: "changeme" writeBehind: modificationQueueSize: "2048" failSilently: "true"
ConfigurationBuilder
ConfigurationBuilder builder = new ConfigurationBuilder(); builder.persistence() .async() .modificationQueueSize(2048) .failSilently(true);
静默失败
write-behind 配置包含一个 fail-silently
参数,用于控制缓存存储不可用或者修改队列已满时发生的情况。
-
如果
fail-silently="true"
,Data Grid 会记录 WARN 消息并拒绝写操作。 如果
fail-silently="false"
,如果 Data Grid 在写操作过程中检测到缓存存储不可用,则 Data Grid 会抛出异常。同样,如果修改队列已满,Data Grid 会抛出异常。在某些情况下,如果修改队列中存在 Data Grid 重启和写操作,则可能会出现数据丢失。例如,缓存存储离线,但在检测缓存存储不可用时,写入操作会添加到修改队列中,因为它没有满。如果在缓存存储恢复前 Data Grid 重启或其他不可用,则修改队列中的写入操作将会丢失,因为它们不会被保留。