良好的快照表数据结构可用于内存索引


12

我正在为一个非常特殊的用例设计内存对象数据库。它是单个编写器,但必须支持有效的并发读取。读取必须隔离。没有查询语言,数据库仅支持:

  • 通过属性/属性集获取对象(例如,可能支持表达式x.count < 5
  • 获取对象的属性

查询是命令脚本,由任意数量的上述操作组成。数据大小将是<< <<内存,因此大多数属性上的所有对象和索引都应舒适地容纳而无需交换。

我需要的是对象属性索引的数据结构,该数据结构在写入时可以为O(n),不支持写入并发,但理想情况下应支持O(1)快照(可能在写入时进行复制)和O(logN)访问。理想情况下,这将允许读取时具有高并发性,并在版本之间实现最大的结构共享。

我当时在看CTries并发BST并发Splay 树,但是我不确定我是否真的在朝正确的方向看。上面的结构非常关注我不关心的插入物的复杂性。

问题:是否有一个现成的数据结构适合我的用例?

编辑:经过更多思考之后,似乎持久的BST / Splay树将起作用。编写者将更新“主”副本,查询将在执行开始时获得该树,并在完成后将其丢弃。但是,我仍然对是否有更好的解决方案感兴趣。


1
您是否需要内存中的快照,还是需要将其保存到磁盘/网络中?纯粹的功能性数据结构会自动为您提供内存中快照,因此,如果您需要它,那将是您的最佳选择。
吉尔斯(Gillles)“所以-别再作恶了”

全部都在内存中。我想知道也许有一个具有恒定时间快照的高效可变版本(例如CTrie,仅没有并发写入)。
dm3

2
您的问题可能不是数据结构的选择,而是并发控制的类型。
拉斐尔

可能是,您能否再详细说明一点?
dm3

Answers:


5

使用任何一种基于树的持久性/不变性(即功能性)数据结构。正如@Raphael在评论中指出的那样,关键是要正确锁定。

基于功能/持久树的数据结构的好处是,您可以免费获得“快照”。假设您对数据结构使用了treap(随机二进制搜索树)。这是用Go语言编写的示例:https : //github.com/steveyen/gtreap。作者对此进行了描述:

不可变地,对陷阱的任何更新/删除都将返回一个新的陷阱,该新陷阱可以与先前的陷阱共享内部节点。创建后,此实现中的所有节点均为只读。这允许并发读取器与并发写入器安全地操作,因为修改只会创建新的数据结构,而不会修改现有的数据结构。这是实现MVCC或多版本并发控制的简单方法。

O(logn)

您使用锁来保护指向根的指针。由于数据结构是不可变的,因此可以同时进行读取,并且可以保存指向旧快照的指针。读为:

lock
tmp = ptr_to_root
unlock
value = search(tmp, <value to search for>)
return value

即使搜索可能需要一段时间,您在复制指针时只握住锁,因此搜索可以同时发生。

写为:

lock
old_ptr_to_root = ptr_to_root
ptr_to_root = insert(old_ptr_to_root, <new key/value pair>)
unlock

在此版本中,写入程序确实需要在创建树的新版本的整个过程中保持锁定。您可以通过将写入更改为以下内容来提高读取性能(有时会导致写入事务失败):

top:
  lock
  old_ptr_to_root = ptr_to_root
  unlock
  new_ptr_to_root = insert(old_ptr_to_root, <new key/value pair>)
  lock
  if (ptr_to_root == old_ptr_to_root)   # make sure no other write happened in the interim
    ptr_to_root = new_ptr_to_root
    unlock
  else                                  # transaction fails, try again
    unlock
    goto top

如果您的编程语言具有原子比较和交换操作的原子变量,则您甚至可以做得更好(使其“无锁”)。(例如,使用C ++ 11。atomic<T*>


感谢您的详尽回答。我有点知道,也许我在问题本身中的意思不够清楚。但是,答案还是不错的!
2015年

您的“改进”版本取决于所用系统的内存模型。在某些系统上,很可能需要将verables声明为volatile,并且需要精湛的技巧才能使编码正确。
伊恩·林罗斯

1

Microsoft已发布了有关其新的内存数据库的详细信息,它的索引不会在写入完成时阻止读取。

例如:

Justin Levandoski,David Lomet和Sudipta Sengupta,Bw树:新硬件的B树,在2013年IEEE第29届国际数据工程会议(ICDE)和国际数据工程会议上,2013年4月8日。

有关其出版物的列表,请参见http://research.microsoft.com/zh-cn/projects/main-memory_dbs/

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.