在内存关系数据库中

我知道这个问题在stackoverflow中被多次询问。 我发布这个问题,以找出什么是我的devise的最佳select。 我有我的工作细节以下架构。

_unique_key varchar(256) NULL _job_handle varchar(256) NULL _data varchar(1024) NULL _user_id int(11) NULL _server_ip varchar(39) NULL _app_version varchar(256) NULL _state int(11) NULL _is_set_stopped bool 

我们在这张桌子上做了什么样的操作:

  1. 对于每个工作,我们将在此表上进行一次更新和10个select查询。 所以我们需要高频率来读写。
  2. 有很多应用程序正在通过对其进行过滤来操纵此表:
    1. _unique_key
    2. _州
    3. is_set_stopped
    4. _用户名
  3. _data字段大小根据应用程序和用户的types从5KB到1MB不等。
  4. 应用程序可以更新select属性

我们认为解决scheme

MySQL的InnoDB

由于高读写要求,我认为MySQL不会有足够的扩展性。

MySQL在内存表

这个解决scheme的问题在于

  1. 它不支持dynamic字段大小。 MEMORY表使用固定长度的行存储格式。 可变长度types(如VARCHAR)使用固定长度进行存储。 来源http://dev.mysql.com/doc/refman/5.0/en/memory-storage-engine.html
  2. select….更新它将locking整个表。 我不知道这会是一个问题。

Redis

Redis看起来是个不错的select。 但是我认为我的表对于键值caching服务器来说并不好。

  1. 它只支持我们的数据types集。 我只能在列表中存储string。 我需要将字段存储为JSON或其他格式。
  2. 如果客户想要更新一个特定的属性,他们需要下载完整的值,然后parsing对象并重新映射到服务器。 可能是我错了有没有办法做到这一点?
  3. 基于价值的过滤是不可能的。 可能是我错了有没有办法做到这一点?

MySQL InnoDB在TMPFS文件系统上

这看起来有希望。 但是,在内存表中,它不会像Redis或MySQL那样足够大。

在这个问题中,您将原始性能(即效率)与可伸缩性混为一谈。 他们是不同的概念。

在InnoDB和内存引擎之间,InnoDB可能是最具扩展性的。 InnoDB支持多版本并发控制,有很多优化来处理争用,所以它会比内存引擎更好地处理并发访问。 即使在某些I / O限制的情况下可能会比较慢。

Redis是一个单线程服务器。 所有的操作都是序列化的。 它具有零可扩展性。 这并不意味着效率低下。 相反,它可能会支持MySQL(由于其基于epoll的事件循环)和更多流量(由于其非常有效的无锁实现和内存数据结构)而产生的更多连接。

为了回答你的问题,我会试试InnoDB的MySQL。 如果配置正确(没有同步提交,足够的缓存等),它可以保持一个很好的吞吐量。 而不是在tmpfs上运行它,我会考虑SSD硬件。

现在,如果你喜欢使用Redis(这不是一个关系型商店btw),你当然可以做到这一点。 没有必要系统地序列化/反序列化您的数据。 过滤的确是可能的,只要你能预见所有的访问路径并找到一个适合的数据结构。

例如:

  • 每个作业一个哈希对象。 关键是_unique_key。 散列的字段应与您的关系表的列相对应。
  • 每个国家一套价值
  • 2套is_set_stopped
  • 每个userid值一个集合

对于每个作业插入,您需要管道以下命令:

 HMSET job:AAA job_handle BBB data CCC user_id DDD server_ip EEE app_version FFF state GGG is_set_stopped HHH SADD state:GGG AAA SADD is_set_stopped:HHH AAA SADD user_id:DDD AAA 

只要您维护相应的设置,您可以轻松地更新任何字段。

您可以通过交集集来执行过滤查询。 例如:

 SINTER is_set_stopped:HHH state:GGG 

使用Redis时,瓶颈将可能是网络,特别是在数据字段很大的情况下。 我希望你会有比1MB的工作多5KB的工作。 例如,1000 MB / s的1 MB对象代表8 GBits / s,可能比您的网络所能承受的更多。 Redis和MySQL都是如此。

我建议postgresql,它比mysql更有能力(有更多的功能和更好的支持复杂的查询和数据类型),并有很多调优选项。

如果你给postgresql足够的内存,并调整参数,它会缓存所有内存。

另外,你也可以在tmpfs上使用它,如果这是你的首选项,并使用流式复制到硬盘上的磁盘数据库。

流式复制异步,接收和fsync有3种操作模式。 如果您使用第一个异步服务器,则不必等待复制服务器上的磁盘同步,因此使用tmpfs时,任何更新都将非常快速。

由于您似乎还有很多文本字段,所以另一个功能可能会有所帮助,postgresql可以将一个文本搜索向量存储在一行中,并且您可以添加一个索引并通过触发器更新它,并将所有行的连接内容正在搜索。 当你在多列上进行文本搜索的时候,这会给你一个难以置信的提升,而不是任何你可能用mysql编写的方式。

无论您使用的数据库如何

你声明_data是varchar [1024],但你说它包含5K到1M的数据? 这实际上是一个blob? 即使是长度错误,mysql也不支持长度超过65535字节的varchar字段! 我想这不会像其他行那样更新,将它分成两个表格是很明智的,一个是静态数据,另一个是动态数据,以最小化磁盘访问。