我正在研究一个项目,我们是批量加载并在Oracle数据库中存储大量数据,这些数据经常通过Hibernate对这个1亿多个记录表进行查询(读取比写入更频繁)。 为了加快速度,我们使用Lucene进行一些查询(尤其是地理边界框查询)和Hibernate二级缓存,但这仍然不够。我们仍然遇到针对Oracle的Hibernate查询的瓶颈(由于缺少那么多内存,我们不会在Hibernate二级缓存中缓存超过1亿个表实体)。
在这种情况下,我可以利用哪些额外的NoSQL解决方案(除了Lucene)?
我想到的一些选择是:
在Hibernate二级中使用分布式ehcache(Terracotta)来跨机器利用更多内存并减少重复缓存(现在每个VM都有自己的缓存)。
要完全在内存中使用像H2这样的SQL数据库,但不幸的是,这些解决方案需要将100多万个表加载到单个VM中。
使用Lucene进行查询,使用BigTable(或分布式hashmap)进行实体查找。 什么BigTable实现适合这个?我在考虑HBase。
使用MongoDB存储数据以及通过id查询和查找。
答案 0 :(得分:6)
推荐使用ElasticSearch的Cassandra实现可扩展的系统(1亿对他们来说没什么)。对于所有数据使用cassandra,对于临时和地理查询使用ES。然后你可以杀死整个遗留堆栈。您可能需要像rabbitmq这样的MQ系统来实现Cass之间的数据同步。和ES。
答案 1 :(得分:2)
这实际上取决于您的数据集。 NoSQL设计的首要规则是首先定义您的查询方案。一旦你真正理解了如何查询数据,那么你可以查看各种NoSQL解决方案。默认的分配单位是关键。因此,您需要记住,您需要能够在节点机器之间有效地分割数据,否则您将最终得到一个水平可伸缩的系统,所有工作仍在一个节点上完成(尽管根据具体情况更好的查询)。
您还需要回顾CAP定理,大多数NoSQL数据库最终都是一致的(CP或AP),而传统的Relational DBMS是CA.这将影响您处理数据和创建某些事物的方式,例如密钥生成可能会变得棘手。
还记得比HBase等系统中没有索引概念。您的应用程序逻辑需要构建所有索引,并且需要对所有更新和删除进行管理。使用Mongo,您实际上可以在字段上创建索引并相对快速地查询它们,还可以将Solr与Mongo集成。您不仅需要在Mongo中按ID查询,就像在HBase中进行查询一样,这是一个列族(也称为Google BigTable样式数据库),您实际上拥有嵌套的键值对。
因此,再次涉及到您的数据,您要存储的内容,您计划如何存储它,以及最重要的是您希望如何访问它。 Lily项目看起来非常有前途。我参与的工作是从网络上获取大量数据,我们将其存储,分析,剥离,解析,分析,流式传输,更新等等。我们不只是使用一个系统而是很多最适合手头的工作。对于这个过程,我们在不同阶段使用不同的系统,因为它使我们能够快速访问我们需要的地方,提供实时流式传输和分析数据的能力,重要的是,随时跟踪所有内容(如生产中的数据丢失)系统是一个大问题)。我正在使用Hadoop,HBase,Hive,MongoDB,Solr,MySQL甚至是好的旧文本文件。请记住,使用这些技术生产系统比在服务器上安装Oracle要困难一些,有些版本不稳定,你真的需要先进行测试。在一天结束时,它实际上取决于业务阻力水平和系统的任务关键性。
迄今为止没有人提到的另一条路径是NewSQL--即水平可扩展的RDBMS ......有一些像MySQL集群(我认为)和VoltDB可能适合你的原因。
同样,要了解您的数据和访问模式,NoSQL系统也是非Rel,即非关系,并且更适合非关系数据集。如果您的数据本质上是关系型的,并且您需要一些真正需要执行诸如笛卡尔积(也称为连接)之类的SQL查询功能,那么您可能更好地坚持使用Oracle并在索引,分片和性能调整方面投入一些时间。
我的建议是实际使用几种不同的系统。看看;
MongoDB - 文档 - CP
CouchDB - 文档 - AP
Redis - 在内存键值(非列族)中 - CP
Cassandra - 专栏系列 - 可用&分区容忍(AP)
HBase - 列族 - 一致&分区容忍(CP)
<强>的Hadoop /蜂房强>
VoltDB - 一个非常好看的产品,一个分布式的关系数据库,可能适用于您的情况(可能更容易移动)。它们似乎也提供了企业支持,这可能更适合产品环境(即为商业用户提供安全感)。
任何方式都是我的2c。玩弄系统真的是你找出真正适用于你的情况的唯一方法。
答案 2 :(得分:1)
正如您所说,MongoDB(或任何类似的NoSQL持久性解决方案)适合您。我们运行的测试数据集明显大于您在MongoDB上建议的数据集,并且工作正常。特别是如果您阅读了大量的MongoDB,那么跨复制集成员的分片和/或分发读取将允许您显着加快查询速度。如果您的用例允许保持索引正确平衡,那么接近20毫秒的查询目标应该变得可行,而无需进一步缓存。
答案 3 :(得分:1)
您还应该查看Lily项目(lilyproject.org)。他们将HBase与Solr集成在一起。在内部,他们使用消息队列来保持Solr与HBase同步。这使得它们具有solr索引(分片和复制)的速度,并得到高度可靠的数据存储系统的支持。
答案 4 :(得分:0)
你可以分组请求和将它们分解为一组数据&amp;拥有一个(或一组服务器)进程,在这里您可以在缓存中提供数据以提高性能。
如,
说,员工&amp;使用10个表处理可用性数据,当您将hibernate缓存配置为load&amp; amp时,这些表可以在一小组服务器上处理。处理请求。
要使其工作,您需要一个负载均衡器(按业务场景平衡负载)。
不确定这里可以实施多少。
答案 5 :(得分:0)
在100M记录中,你的瓶颈可能是Hibernate,而不是Oracle。我们的客户通常在我们基于Oracle的数据仓库的各个事实表中拥有数十亿条记录,并且处理得很好。
您在桌面上执行了哪些查询?