【问题标题】:Atomic operation to set minimum value in an Aerospike bin在 Aerospike 垃圾箱中设置最小值的原子操作
【发布时间】:2018-11-07 06:25:12
【问题描述】:

我需要 Aerospike 的原子“设置最小值”操作,其中我给出一个 bin 名称和一个数字参数,并设置并返回 bin 的当前值或参数中的较低值。

以下 Lua UDF 应该可以工作

test.lua

function set_min(rec, bin_name, value)
    if aerospike:exists(rec) then
        local min = rec[bin_name]
        if min > value then
            rec[bin_name] = value
            aerospike:update(rec)
        end
    else
        rec[bin_name] = value
        aerospike:create(rec)
    end
    return rec[bin_name]
end

使用参数 11、9、5、7 运行:

aql> execute test.set_min('minval', 11) on test.set-min where PK=2
+---------+
| set_min |
+---------+
| 11      |
+---------+
1 row in set (0.001 secs)

OK

aql> execute test.set_min('minval', 9) on test.set-min where PK=2
+---------+
| set_min |
+---------+
| 9       |
+---------+
1 row in set (0.001 secs)

OK

aql> execute test.set_min('minval', 5) on test.set-min where PK=2
+---------+
| set_min |
+---------+
| 5       |
+---------+
1 row in set (0.001 secs)

OK

aql> execute test.set_min('minval', 7) on test.set-min where PK=2
+---------+
| set_min |
+---------+
| 5       |
+---------+
1 row in set (0.000 secs)

还有其他方法吗?

【问题讨论】:

    标签: types lua user-defined-functions aerospike


    【解决方案1】:

    在任何数据库中,用户定义的函数都会比本地操作运行得慢。这在 Aerospike 中没有什么不同,Lua UDF 的延迟会更高,并且不会像原生操作那样扩展。

    Aerospike 的 List 和 Map 数据类型具有广泛(且不断增长的)原子操作 API。这些操作可以组合成一个单一的多操作​​事务(使用operate()方法)。

    我们可以利用有序列表来执行与上述 UDF 相同的原子操作,以一种运行速度更快、扩展性更好的方式。

    set_min.py

    from __future__ import print_function
    import aerospike
    from aerospike import exception as e
    from aerospike_helpers.operations import list_operations as lh
    import pprint
    import sys
    
    def set_min(bin_name, val):
        list_policy = {
            "list_order": aerospike.LIST_ORDERED,
            "write_flags": (aerospike.LIST_WRITE_ADD_UNIQUE |
                            aerospike.LIST_WRITE_PARTIAL |
                            aerospike.LIST_WRITE_NO_FAIL)
        }
        ops = [
            lh.list_append(bin_name, val, list_policy),
            lh.list_remove_by_rank_range(bin_name, 0, aerospike.LIST_RETURN_NONE,
                1, True),
            lh.list_get_by_rank(bin_name, 0, aerospike.LIST_RETURN_VALUE)
        ]
        return ops
    
    config = {'hosts': [('172.16.39.132', 3000)]}
    client = aerospike.client(config).connect()
    pp = pprint.PrettyPrinter(indent=2)
    key = ('test', 'set-min', 1)
    
    key, meta, bins = client.operate(key, set_min('minval', 11))
    pp.pprint(bins['minval'])
    
    key, meta, bins = client.operate(key, set_min('minval', 9))
    pp.pprint(bins['minval'])
    
    key, meta, bins = client.operate(key, set_min('minval', 5))
    pp.pprint(bins['minval'])
    
    key, meta, bins = client.operate(key, set_min('minval', 7))
    pp.pprint(bins['minval'])
    
    client.close()
    

    使用参数 11、9、5、7 运行:

    11
    9
    5
    5
    
    1. 使用有序列表,将唯一值添加到列表中, 如果该值已经存在,则优雅地失败。该清单应 现在有一个或两个元素。
    2. 该列表被修剪以仅包含排名最低的元素。
    3. 返回排名最低的元素(应该只有一个在列表中)。

    这三个操作在记录锁下自动发生。

    有关参考,请参阅docs for the Python client。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-06-14
      • 1970-01-01
      • 2019-03-15
      • 2021-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多