Remote Cache, Transaction

本文探讨了RemoteCache与LocalCache的区别,介绍了ClusterCache的工作原理及优势,并讨论了在ORM中的应用,包括事务处理策略和Cache的一致性问题。
1. Remote Cache

Remote Cache 是对应于Local Cache来说的。
Key or Value 需要序列化,需要内部网络通信。

Remote Cache 可分为 中心Cache,和Cluster Cache。

Cluster Cache的一个要点是,只是remove的时候,传播 invalidate事件。
这样只需要在 update 的时候,进行传播。
好处是,读取的时候,比起中心cache,就少了一布内部网络通信。
坏处是,命中率比memcache低,因为memory是分开的。update多的时候,需要传播 remove/invalidate事件。

2. ORM, Transaction.
Cache通常用于ORM中。人们通常考虑Cache 和 DB 的同步,甚至事务。其实不用考虑到那么细粒度。
比如,Cache 的 Read Committed 没有必要保证,可以允许一定的read committed。
原因很简单。即使是保证了read commited隔离级别的db 操作,都无法解决数据库事务并发冲突问题。只能依靠应用程序层的 悲观锁 和 乐观锁 来解决。
所以,严格保证Cache 的 Read Committed 没有意义。

至于Cache 和 DB Transaction 是否应该成为一个原子操作,统一为一个Transaction。这也只是一个概念上的事情。就看时间点如何纪录。
而且,处于和上面同样的道理,保证这个transaction也没有意义.

3. My Idea.
lightor中,我是这么处理Cache的。

首先,根本不考虑 Read Commited。甚至采用 Copy On Write 这样的方式,鼓励 Read Dirty, 增加命中率。

其次,cache模型非常简单,比map还要简单,根本不考虑时间锁之类的东西。
cluster mode中只需要传播一个 remove 事件。这个可以用底层open source cache 的实现直接支持。

再次,为了增强对 remote cache (中心cache, cluster cache)的支持,cache 实现中,都有大粒度调用方式的支持。这些支持是任何cache都没有考虑的。
比如,get(key),remove(key),
如果这个key,是一个 object[], collection,那么返回值也是一个collection。
这样,如果远程访问这个cache 的时候,一次通信可以完成很多工作。避免多次通信。
putAll( pairs ) 方法也是这样。
这种大粒度调用方式的实现,对于实现关联Cache非常有意义。
/* * @(#)FlinkDMCDC.java, 2023年8月5日 上午10:33:17 * * Copyright (c) 2000-2020, 达梦数据库有限公司. * All rights reserved. */ package com.dameng.flinkcdc.dm; import java.util.Properties; import org.apache.flink.api.common.eventtime.WatermarkStrategy; import org.apache.flink.cdc.connectors.base.options.StartupOptions; import org.apache.flink.cdc.connectors.base.source.jdbc.JdbcIncrementalSource; import org.apache.flink.cdc.connectors.dm.source.DMSourceBuilder; import org.apache.flink.cdc.debezium.JsonDebeziumDeserializationSchema; import org.apache.flink.configuration.Configuration; import org.apache.flink.runtime.state.filesystem.FsStateBackend; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; /** * * Created by wuxin on 2023年8月5日 上午10:33:17 */ public class FlinkDMCDC { public static void main(String[] args) throws Exception { Properties properties = new Properties(); properties.setProperty("database.tablename.case.insensitive", "false"); properties.setProperty("log.mining.strategy", "offline_catalog"); properties.setProperty("log.mining.continuous.mine", "true"); //properties.setProperty("provide.transaction.metadata", "true"); properties.setProperty("lob.enabled", "true"); // String format = "<local-cache name=\"%s\"><persistence passivation=\"false\"><file-store fetch-state=\"true\" read-only=\"false\" preload =\"true\" shared=\"false\" path=\"./data\" /></persistence></local-cache>"; // properties.setProperty("log.mining.buffer.type", "infinispan_embedded"); // properties.setProperty("log.mining.buffer.infinispan.cache.transactions", String.format(format, "transactions")); // properties.setProperty("log.mining.buffer.infinispan.cache.events", String.format(format, "events")); // properties.setProperty("log.mining.buffer.infinispan.cache.processed_transactions", String.format(format, "processed_transactions")); // properties.setProperty("log.mining.buffer.infinispan.cache.schema_changes", String.format(format, "schema_changes")); // // String format = "<distributed-cache name=\"%s\"><encoding media-type=\"application/x-protostream\" /><persistence passivation=\"false\"><file-store shared=\"false\"/></persistence></distributed-cache>"; // properties.setProperty("log.mining.buffer.type", "infinispan_remote"); // properties.setProperty("log.mining.buffer.infinispan.cache.transactions", String.format(format, "transactions")); // properties.setProperty("log.mining.buffer.infinispan.cache.events", String.format(format, "events")); // properties.setProperty("log.mining.buffer.infinispan.cache.processed_transactions", String.format(format, "processed_transactions")); // properties.setProperty("log.mining.buffer.infinispan.cache.schema_changes", String.format(format, "schema_changes")); // properties.setProperty("log.mining.buffer.infinispan.client.hotrod.server_list", "223.254.6.38:11111"); // properties.setProperty("log.mining.buffer.infinispan.client.hotrod.auth_username", "admin"); // properties.setProperty("log.mining.buffer.infinispan.client.hotrod.auth_password", "admin"); // properties.setProperty("log.mining.buffer.infinispan.client.hotrod.socket_timeout", "600000_000"); JdbcIncrementalSource<String> changeEventSource = new DMSourceBuilder<String>() .hostname("10.150.4.30") .port(5236) .databaseList("AUTH") .tableList("AUTH.P_05_USER") // .tableList("TEST.T1") .schemaList("AUTH") .username("SYSDBA") .password("SYSDBA") .startupOptions(StartupOptions.initial()) .dmProperties(properties) .includeSchemaChanges(true) .deserializer(new JsonDebeziumDeserializationSchema()) // .deserializer(new CustomerDeserializationSchema()) .sliceSize(20) .scanNewlyAddedTableEnabled(true) .build(); Configuration configuration = new Configuration(); //检查点文件 // configuration.setString("execution.savepoint.path", new File("D:\\tmp\\ck\\a63f3d853cbd861de5e94e4fdded257a\\chk-2").toPath().toUri().toString()); StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(configuration); // StreamExecutionEnvironment env = StreamExecutionEnvironment.createRemoteEnvironment("10.136.110.21", 8099); env.enableCheckpointing(20 * 1000); env.getCheckpointConfig().setMinPauseBetweenCheckpoints(6*1000); env.getCheckpointConfig().setMaxConcurrentCheckpoints(1); env.setStateBackend(new FsStateBackend("file:///home/yyq/ck")); // env.setStateBackend(new FsStateBackend("file:///D:/tmp/ck")); /* env.enableCheckpointing(60 * 1000); env.getCheckpointConfig().setCheckpointTimeout(3600*1000); env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE); env.getCheckpointConfig().setMinPauseBetweenCheckpoints(1000); env.getCheckpointConfig().setMaxConcurrentCheckpoints(1); env.getCheckpointConfig().setFailOnCheckpointingErrors(false); // env.setStateBackend(new FsStateBackend("file:///D:/tmp/ck")); */ // env.addSource(sourceFunction) // //.writeAsText("D:\\flink_java\\flink-cdc-oracle-output.txt", WriteMode.OVERWRITE).setParallelism(1); // .print().setParallelism(1); env.fromSource(changeEventSource, WatermarkStrategy.noWatermarks(), "DmSource") .setParallelism(1) .print() //.writeAsText("/home/wuxin/dm-output.txt", WriteMode.OVERWRITE) .setParallelism(1); env.execute(); } } 获取变更行,所有列的数据 ,这个代码有问题吗?
最新发布
11-22
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值