max*_*max 31 python database google-app-engine
我必须以"强烈单调增长"的方式标记某些东西.无论是发票号码,运输标签号码等.
花哨的说法:我需要计算1,2,3,4 ...我可用的空间数通常是100.000个数字,我每天需要1000个.
我知道这在分布式系统中是一个难题,而且我们通常使用GUID更好.但在这种情况下,出于法律原因,我需要"传统编号".
这可以在Google AppEngine上实现(最好是在Python中)吗?
Nic*_*son 25
如果您必须按顺序增加数字而没有间隙,则需要使用单个实体,在事务中更新该实体以"消耗"每个新数字.在实践中,你将被限制为每秒产生大约1-5个数字 - 这听起来对你的要求很好.
如果删除ID必须严格顺序的要求,则可以使用分层分配方案.基本思想/限制是事务不得影响多个存储组.
例如,假设您具有"用户"的概念,则可以为每个用户分配一个存储组(为每个用户创建一些全局对象).每个用户都有一个保留ID列表.为用户分配ID时,选择一个保留的ID(在事务中).如果没有剩下ID,则使新事务从全局池中分配100个ID(比如说),然后创建一个新事务将它们添加到用户并同时撤销一个.假设每个用户只是顺序地与应用程序交互,那么用户对象就不会有并发性.
该gaetk -谷歌的AppEngine工具包现在配备了一个简单的库函数在一个序列得到的一个数字.它基于尼克约翰逊的交易方法,可以很容易地用作MartinvonLöwis的分片方法的基础:
>>> from gaeth.sequences import *
>>> init_sequence('invoce_number', start=1, end=0xffffffff)
>>> get_numbers('invoce_number', 2)
[1, 2]
Run Code Online (Sandbox Code Playgroud)
该功能基本上是这样实现的:
def _get_numbers_helper(keys, needed):
results = []
for key in keys:
seq = db.get(key)
start = seq.current or seq.start
end = seq.end
avail = end - start
consumed = needed
if avail <= needed:
seq.active = False
consumed = avail
seq.current = start + consumed
seq.put()
results += range(start, start + consumed)
needed -= consumed
if needed == 0:
return results
raise RuntimeError('Not enough sequence space to allocate %d numbers.' % needed)
def get_numbers(needed):
query = gaetkSequence.all(keys_only=True).filter('active = ', True)
return db.run_in_transaction(_get_numbers_helper, query.fetch(5), needed)
Run Code Online (Sandbox Code Playgroud)
如果你对顺序不太严格,你可以"加"你的增量器.这可以被认为是"最终顺序"的反击.
基本上,您有一个实体是"主"计数.然后,您有许多具有自己的计数器的实体(基于您需要处理的负载).这些分片从主服务器中保留了一大块ID,并从它们的范围中提供服务,直到它们用完了值.
快速算法:
n为其添加一个数量.将分片开始设置为检索到的值加1并结束检索到的加号n.这可以很好地扩展,但是,你可以超出的数量是碎片数量乘以你的n值.如果您希望您的记录显示为上升,则可能会有效,但如果您希望它们代表订单则不准确.同样重要的是要注意最新的值可能有漏洞,因此如果您使用它来扫描某些原因,您将不得不考虑这些漏洞.
我需要这个用于我的应用程序(这就是我在搜索问题的原因:P)所以我已经实现了我的解决方案.它可以获取单个ID以及有效地获取批次.我在受控环境(在appengine上)进行了测试,并且表现非常好.你可以在github上找到代码.
| 归档时间: |
|
| 查看次数: |
11143 次 |
| 最近记录: |