用于存储大型基于数据/数组的数据的高写并发后端?

时间:2016-09-27 14:59:24

标签: sqlite concurrency cassandra redis persistence

问题:
我有一个Web服务,需要根据一组字符串检查给定字符串的成员资格,其中集合中的元素数量将不断增长,可能数以亿计。

如果字符串不是该集合的成员,则会将其添加到集合中。字符串大小将是一个常量32个字节。只需要一个set变量,不需要保留其他变量。

此检查是作为webhook上回调的一部分执行的,因此性能至关重要。

虽然我的用例非常适合布隆过滤器,但我很难找到解决问题的持久存储与i / o并发部分的解决方案。

环境: DigitalOcean / Linux / Python / Flask,但如果需要可以更改

可能的解决方案:

redis ,将变量存储在一个集合中,然后通过sismember查询一个不错的基于o(1)的解决方案。这是我们目前正在使用的,但是这个解决方案不能很好地扩展到大量的密钥,因为一切都必须适合内存,并且当流量增加时它也会出现写并发问题。

sqlite ,打开WAL模式。关注服务器被大量webhook请求(SQLITE_BUSY)命中时的锁争用。本地服务器文件不能跨主机进行扩展。

postgres ,似乎是一个很好的中间解决方案,但可能必须处理此处的锁争用以及写并发。

cassandra ,因为它专注于写性能。虽然存储单个列的过度杀伤?

自定义bloom过滤后端,不确定是否存在提供具有高i / o并发存储后端的bloom过滤器功能的类似内容。

思想?

2 个答案:

答案 0 :(得分:1)

Redis解决方案可以通过数据分片很好地扩展。您可以设置多个Redis实例(或使用Redis-Cluster),将数据拆分为多个部分,即分片,并将每个部分保存在不同的Redis实例中。

如果要检查给定字符串的成员资格,可以将sismenber命令发送到相应的Redis实例。以this answer为例,说明如何使用哈希函数分割数据。

此外,您可以使用Redis(GETBITSETBIT)实现bloom过滤器。只是提醒一下,布隆过滤器有误报问题。

答案 1 :(得分:1)

首先,您不需要使用sismember。系统地做sadd,并测试返回的值。如果它为0,则该值已经在集合中,因此未添加。这样做可以非常轻松地减少对Redis的请求数量。

其次,对问题的描述看起来像Hbase的完美匹配,Hbase用于存储非常大的数据集并使用bloom过滤器查询它们。但你可能会发现它有点矫枉过正,就像Cassandra一样。