Locking 如何在Geode区域中存储相关条目

Locking 如何在Geode区域中存储相关条目,locking,region,gemfire,geode,Locking,Region,Gemfire,Geode,我们对草图(大小可以从1GB到15GB不等)进行操作,目前将其分成若干个包裹(每个包裹大约50mb),并将这些包裹存储在Geode分区区域中,我们从S3读取这些数据,然后将它们全部放在该区域中。一旦成功,我们将在区域中插入一个条目(标记键)。这个标记键在我们的业务逻辑中非常重要 下面是区域配置 <region name="region_abc"> <region-attributes data-policy="partition"

我们对草图(大小可以从1GB到15GB不等)进行操作,目前将其分成若干个包裹(每个包裹大约50mb),并将这些包裹存储在Geode分区区域中,我们从S3读取这些数据,然后将它们全部放在该区域中。一旦成功,我们将在区域中插入一个条目(标记键)。这个标记键在我们的业务逻辑中非常重要

下面是区域配置

<region name="region_abc">
    <region-attributes data-policy="partition" statistics-enabled="true">
        <key-constraint>java.lang.String</key-constraint>
        <entry-time-to-live>
            <expiration-attributes action="destroy" timeout="86400"/>
        </entry-time-to-live>
        <partition-attributes redundant-copies="0">
            <partition-resolver name="SingleBucketPartitioner">
                <class-name>com.companyname.geode.sketch.partition.SingleBucketPartitioner</class-name>
            </partition-resolver>
        </partition-attributes>
        <cache-loader>
            <class-name>com.companyname.geode.abc.cache.BitmapSketchParcelCacheLoader</class-name>
            <parameter name="s3-region-name">
                <string>us-east-1</string>
            </parameter>
            <parameter name="s3-bucket-name">
                <string>xyz</string>
            </parameter>
            <parameter name="s3-folder-name">
                <string>abc</string>
            </parameter>
            <parameter name="s3-read-timeout">
                <string>600</string>
            </parameter>
            <parameter name="read-through-pool-size">
                <string>70</string>
            </parameter>
            <parameter name="measurement-group">
                <string>abcd</string>
            </parameter>
        </cache-loader>
        <cache-listener>
            <class-name>com.companyname.geode.abc.cache.ClearMarkerKeyAfterAnyEntryDestroyCacheListener</class-name>
        </cache-listener>
        <eviction-attributes>
            <lru-heap-percentage action="local-destroy"/>
        </eviction-attributes>
    </region-attributes>
</region>

java.lang.String
com.companyname.geode.sketch.partition.SingleBucketPartitioner
com.companyname.geode.abc.cache.BitmapSketchParcelCacheLoader
美国东部-1
xyz
abc
600
70
abcd
com.companyname.geode.abc.cache.ClearMarkerKeyAfterAnyEntryDestroyCacheListener
如果标记关键点存在于区域中,则我们假设我们拥有草图的所有条目

我们目前已将缓存逐出设置为在堆使用率的70%时触发,这将使用LRU算法逐出缓存项。由于缓存被逐出,我们已经看到数据中存在一些不一致之处。我们已经发现了这样的场景:缓存逐出逐出了一些或多个条目,但没有逐出标记键,这给该对象带来了不一致性,因为应用程序认为我们拥有所有条目,但实际上我们没有

为了解决这个问题,我们还为destroy实现了一个侦听器,但不知何故,这也没有解决这个问题

'''

@覆盖
销毁后公共无效(EntryEvent事件){
字符串regionKey=event.getKey();
Region Region=event.getRegion();
//仅当退出非标记键且标记键仍然存在时才执行操作
if(regionKey!=null&&!regionKey.startsWith(“[”)){
//异步调用
重新加载executor.submit(
() -> {
字符串markerKey=“[”.concat(regionKey.substring(0,regionKey.indexOf(“”)).trim().concat(“]);
//在取下标记键之前,检查标记键是否存在
if(区域容器(标记键)){
logger.info(“FIXGEODECACHE:标记键存在!!!删除与输入键关联的标记键。区域:`{}`;输入键:`{}`;标记键:`{}`”,
region.getName(),regionKey,markerKey);
//从区域中删除标记关键点以保持草图的一致性
region.remove(markerKey);
logger.info(“FixGeodeCacheCheunonsistence:标记键已损坏。区域:`{}`;条目键:`{}`;标记键:`{}`,”,
region.getName(),regionKey,markerKey);
}
});
}
}
'''

我们现在正在寻找其他更可靠的解决方案,并试图更深入地研究这个问题

两个音符

  • 我们正在分解一个大对象,并将部分作为条目存储在该区域中
  • 我们向区域添加一个标记键以确定对象的存在
  • 我们从该区域读取该对象的所有部分以创建大对象
  • Geode区域不知道这些零件之间的连接
  • 这是一个简单的例子。 例如,对象是E12345

    • 标记键:-[E12345]
    • 零件/条目:-E12345_00、E12345_01、E12345_02、E12345_03、E12345_04、E12345_05等
    Geode缓存逐出有时会逐出某些部分,但不会逐出标记键,这会导致所有问题。

    我们正试图找到实现以下任一目标的方法

  • 是否有一个将相关条目分组在一起的选项,以便Geode知道这些是一个更广泛对象的相关条目
  • 如何确保Geode缓存逐出不会导致不一致。目前,它正在删除一些条目并保留其中一些条目,这会导致最终结果不一致
  • 这是区域锁定语义的一个好用例吗
  • 我很乐意根据需要提供更多的背景和细节

    欢迎提供任何详细信息/指导/建议

    @Override
    public void afterDestroy(EntryEvent<String, BitmapSketch> event) {
    
        String regionKey = event.getKey();
        Region<String, BitmapSketch> region = event.getRegion();
    
        // take action only when non-marker key is evicted and marker key is still present
        if (regionKey != null && !regionKey.startsWith("[")) {
    
            //asynchronus call
            reloadExecutor.submit(
                    () -> {
    
                        String markerKey = "[".concat(regionKey.substring(0, regionKey.indexOf("_")).trim().concat("]"));
    
                        //check for marker key presence before removing the marker key
                        if (region.containsKey(markerKey)) {
    
                            logger.info("FixGeodeCacheInconsistency : Marker key exist !!! Deleting the marker key associated with the entry key. Region: `{}`;  Entry Key: `{}`;  Marker Key: `{}`",
                                    region.getName(), regionKey, markerKey);
    
                            //remove the marker key from the region to bring consistency for the sketch
                            region.remove(markerKey);
    
                            logger.info("FixGeodeCacheInconsistency : Marker key destroyed. Region: `{}`;  Entry Key: `{}`;  Marker Key: `{}`",
                                    region.getName(), regionKey, markerKey);
    
                        }
                    });
        }
    }