我有两种不同的数据来源,我需要结合在一起。数据集A将具有foo_key属性,该属性可以映射到具有一对多关系的数据集B的bar_key属性。
数据集A:
[{ foo_key: 12345, other: 'blahblah' }, ...]
数据集B:
[{ bar_key: 12345, other: '' }, { bar_key: 12345, other: '' }, { bar_key: 12345, other: '' }, ...]
数据集A来自SQS队列,当我轮询A时,与数据集B的任何关系都可用。
数据集B来自一个单独的SQS队列,我试图将其转储到memcached缓存中,以便在对象进入数据集A时快速查看。
最初我打算从数据集B中的对象设置memcached键为bar_key,但后来意识到如果我这样做,就有可能覆盖该值,因为可能存在许多相同的bar_key值。然后我想我可以创建一个键bar_key,值只是一个SQS消息的数组。但是由于我有多个主机轮询SQS队列,我认为当我检查密钥是否在memcached中时,检查它,将新消息附加到它,然后设置它,另一个主机可能是尝试执行相同的操作,因此第一个主机尝试附加该值只会被覆盖。
我查看了memcached键锁定,但我不确定我完全理解它。解决方案是,当我从memcached获取键/值对时,我在一个名为bar_key_dummy的新键上创建一个临时虚拟锁,该键在x秒后到期,如果我尝试获取一个bar_key_dummy锁激活的键,我只需发送SQS消息返回队列而不删除,在x秒内再试一次?
这是我头脑中的一些伪代码。这有什么意义吗?
store = MemCache.new(host)
sqs_messages.poll do |message|
dummy_key = "#{message.bar_key}_dummy"
sqs.dont_delete_message && next unless store.get(dummy_key).nil?
# set dummy_key in memcache with a value of 1 for 3 seconds
store.set(dummy_key, 1, 3)
temp_data = store.get(message.bar_key) || []
temp_data << message
store.set(message.bar_key, temp_data, 300)
# delete dummy key when done in case shorter than x seconds
store.delete(dummy_key)
end
感谢您的帮助!
答案 0 :(得分:0)
Memcached有一项特殊操作 - cas
比较和交换。
命令gets
返回Item及其唯一的CAS值。
然后可以搜索数据集,并且必须使用cas
命令发布更新,该命令采用原始的唯一CAS值。
如果在两个命令之间更改了CAS,则更新操作将失败并显示EXISTS
错误