如何在分布式环境下将数据附加到Riak密钥?

时间:2013-03-07 14:42:47

标签: riak

使用Riak我希望以一种能够获取我不时附加的所有数据的方式顺序追加数据。想想日志,如果我选择增加的日志行并将它们转移到riak,在某些时候我想要重新构建我所附加的内容。

我想通过为此目的创建一个新存储桶,然后添加由序列号或日期时间戳定义的键,然后将内容添加到其中,然后使用list keys API并重新构建我需要的数据来实现此目的。问题是列表键API效率不高,建议使用生产。我喜欢这种方法的是数据没有并发写入问题(没有锁/等),因为所有键都是独立的。

另一种方法是使用单个密钥,打开它并附加到它,但我非常担心并发/锁定问题。此操作将在分布式环境下执行,并且肯定是一个糟糕的选择

问题:在Riak中还有其他任何方法吗?键的任何附加模式?

1 个答案:

答案 0 :(得分:11)

虽然在写入时将大量小记录写入存储桶很容易且效率很高,但您付出的代价是当您尝试读取值时它会变得昂贵,因为您很可能不会知道密钥。如果您需要通过二级索引,密钥过滤器来查看这些密钥,或者更糟糕的是,通过遍历存储桶中的所有密钥(这是一项非常繁重的操作,从不推荐用于生产环境),这将大大降低效率而不是按键检索数据,而不是按比例缩放。

Riak中也没有附加功能,这意味着您需要先读取然后再写一条记录才能更新它并添加新的日志条目。根据您组织和协调写作的方式,这可以指出同一记录的并发更新结果,这在设计解决方案时需要考虑。

假设您正在收集的记录,例如日志条目,可以视为一个集合,我建议的技术是时间拳击。当时间装箱时,您会根据时间段汇总数据。如果我们例如假设我们正在为一组服务器(在本例中命名为服务器)收集日志,我们可以创建具有基于服务器ID和日期时间标识符的密钥的记录,例如,测量期的开始。我们不需要一个完整的时间戳,足以让我们识别记录。包含2013/03/07 14:15至14:20期间server3的日志条目记录可命名为“server3_20130307_1415”。接下来的5分钟时间将被命名为“server3_20130307_1420”。如果一段时间内没有数据,则不会创建任何记录。

这使您可以自动知道覆盖特定时间段的记录的密钥,并允许您严格按照密钥访问权限检索记录,这些记录可以进行扩展和执行。您自然需要根据生成的数据量调整单个记录所涵盖的时间段,因为您通常希望将Riak中对象的大小保持在1-2MB以下。如果每个时段都有大量数据,那么考虑在应用程序级别压缩数据也是值得考虑的,以便低于建议的大小。

如果您希望能够访问更大的数据块而无需检索可能大量的记录,则可以定期聚合记录。你可以,例如读取涵盖一小时的所有记录,并将汇总数据写入名为“server3_20130307_14”的新记录,该记录涵盖整个时间段14:00-15:00。正如您所知道的那样,这很简单,并且易于作为批处理作业实现。

采用这种方法时,如前所述,您将需要考虑并发写入的可能性。在我看来,最好的方法是允许兄弟姐妹(使用桶属性[1]将'allow_mult'设置为true,将'last_write_wins'设置为false为桶)。这将导致Riak在并发更新的情况下保留记录的所有版本,并且您将需要在读取具有兄弟姐妹的记录时解析在应用程序层中创建的任何兄弟。虽然这确实增加了一些复杂性,但它确保您不会丢失任何数据。

正如我们假设在这种情况下的日志条目可以被视为一个集合,您可以通过集合联合合并所有兄弟的集合,然后更新对象(使用正确的向量时钟)以解析兄弟姐妹。

[1] http://docs.basho.com/riak/latest/references/apis/http/HTTP-Set-Bucket-Properties/