Aerospike首次插入bin数据后执行增量的pid初始化方案咨询
Aerospike 计数器及pid字段初始化最优方案
最优实现方案(基于Aerospike原子操作特性)
Aerospike原生支持单请求内打包多个原子操作,配合操作过滤能力可以完美解决你的问题,完全规避你提到的两个方案的缺陷:
- 每个增量请求仅需1次Aerospike交互,不会造成请求量翻倍
pid字段仅会在记录首次创建时写入1次,不会产生重复写入开销- 计数器无需提前初始化,调用对应增量接口时自动处理不存在的情况
具体实现逻辑
你封装的三个incrementX函数都可以套用统一逻辑:
- 打包两个原子操作到同一个请求中:
- 第一个操作:写入
pid字段,添加操作过滤条件 仅当pid字段不存在时执行写入,已存在的情况下该操作会自动跳过,无额外开销 - 第二个操作:执行对应计数器的
add增量操作,Aerospike原生支持字段不存在时自动初始化为0后再累加,无需提前初始化其他计数器
- 第一个操作:写入
- 调用Aerospike的
operate接口一次性原子执行上述两个操作
伪代码示例:
// incrementA 函数实现示例 public long incrementA(String pk, String pid, int incrementVal) { Key key = new Key("namespace", "set", pk); // 构造原子操作列表 Operation[] ops = new Operation[] { // 仅pid不存在时写入pid Operation.put(new Bin("pid", pid)).setFilter(Exp.not(Exp.binExists("pid"))), // 计数器a增量,不存在则自动从0开始累加 Operation.add(new Bin("a", incrementVal)), // 可选:如果需要返回增量后的a值,加读操作 Operation.get("a") }; // 单次请求执行所有操作 Record record = client.operate(writePolicy, key, ops); return record.getLong("a"); }
补充场景适配
如果你需要保证所有计数器字段在记录中始终存在(比如查询时不想做缺省值判断),可以在操作列表中再增加三个计数器的初始化操作,同样加过滤条件仅当记录不存在时执行,不会影响后续请求的性能。
低版本Aerospike兼容方案
如果你使用的Aerospike版本低于5.2,不支持操作过滤能力,可以用以下降级方案,开销也远低于你之前的方案:
每次调用增量接口时,先尝试用CREATE_ONLY写入策略插入初始化记录(包含pid和三个值为0的计数器),如果写入成功说明是首次创建,直接返回增量后的值;如果写入失败(记录已存在),则直接执行对应计数器的增量操作即可。CREATE_ONLY写入失败的开销极低,99%以上的已存在记录场景下不会产生额外性能损耗。
内容的提问来源于stack exchange,提问作者paradocslover
相关产品推荐
相关产品推荐

