【发布时间】:2017-03-15 04:13:39
【问题描述】:
我想使用 Ignite 集群从现有数据库中加热 PARTITIONED 缓存。现有数据库未分区且扫描成本高,因此我想在集群创建缓存时执行单次扫描。作业完成后,结果将是一个缓存,其中包含现有数据库中的所有数据,这些数据已分区并均匀分布在集群中。
如何实现一个在 Ignite 创建缓存时运行的作业?
【问题讨论】:
标签: ignite
我想使用 Ignite 集群从现有数据库中加热 PARTITIONED 缓存。现有数据库未分区且扫描成本高,因此我想在集群创建缓存时执行单次扫描。作业完成后,结果将是一个缓存,其中包含现有数据库中的所有数据,这些数据已分区并均匀分布在集群中。
如何实现一个在 Ignite 创建缓存时运行的作业?
【问题讨论】:
标签: ignite
Ignite 通过CacheStore [1] 实现与底层存储集成。有关您的特定用例的详细信息,请参阅 [2]。
【讨论】:
CacheStore 时,应该从哪里调用IgniteCache.loadCache?使用IgniteDataStreamer 时,应该从哪里调用addData?似乎该服务不起作用,因为不能保证execute 在集群的整个生命周期内只会被调用一次。或者,EVT_CACHE_STARTED 似乎在每个节点上都在本地发布,因此网格事件将不起作用。一般来说,问题是在哪里实现exactly-once-per-cache逻辑,例如缓存预热。
IgniteCache.loadCache 并在该过程完成后停止客户端。 IgniteDataStreamer 也是如此,通常它是一个客户端节点,从数据库加载数据并将其流式传输到服务器节点。
您可以创建一个Service,它在集群启动时运行一次,然后自行取消。它可以使用缓存来存储状态,因此如果第二次部署在集群中,它将不会运行。
以下抽象服务在集群启动后首次部署时每个集群运行一次executeOnce:
abstract class ExecuteOnceService extends Service {
val ExecuteOnceCacheName = "_execute_once_service"
val config = new CacheConfiguration[String, java.lang.Boolean](ExecuteOnceCacheName)
.setCacheMode(CacheMode.PARTITIONED)
.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL)
@IgniteInstanceResource
var ignite: Ignite = _
override def execute(ctx: ServiceContext): Unit = {
val cache = ignite.getOrCreateCache(config)
val executed = cache.getAndPutIfAbsent(ctx.name(), java.lang.Boolean.TRUE)
if (executed != java.lang.Boolean.TRUE) executeOnce(ctx)
ignite.services().cancel(ctx.name())
}
def executeOnce(ctx: ServiceContext): Unit
}
【讨论】: