所以我一直在努力弄清楚NoSQL是否真的在自动分片和处理UNSTRUCTURED数据之外带来了那么多的价值。
假设我可以将我的STRUCTURED数据放在一台机器上,或者有一个有效的自动分片' SQL的功能,NoSQL选项提供哪些优势?我已经确定了以下内容:
基于文档(MongoDB,Couchbase等) - 除此之外'自动分片'能力,我很难理解其中的好处。链接对象与SQL连接非常相似,而嵌入对象显着膨胀文档大小并导致复制的挑战(注释可能同时属于帖子和用户,因此数据将是多余的)。此外,ACID和交易的损失也是一大缺点。
基于键值(Redis,Memcached等) - 提供不同的用例,非常适合缓存但不是复杂的查询
Columnar(Cassandra,HBase等) - 似乎这里的一大优势是更多的数据如何存储在磁盘上,并且主要用于聚合而不是一般用途
图形(Neo4j,OrientDB等) - 最有趣的是,边缘和节点的使用产生了一个有趣的价值主张,但主要用于高度复杂的关系数据比一般用途。
我可以看到Key-value,Columnar和Graph DB对于特定用例(缓存,社交网络关系映射,聚合)的优势,但是看不出任何理由将MongoDB之类的东西用于外部的STRUCTURED数据它的自动分片'能力。
如果SQL有类似的'自动分片'能力,SQL是结构化数据的明智之举吗?在我看来会是,但我希望社区的意见......
注意:这是关于典型的CRUD应用程序,如社交网络,电子商务网站,CMS等。
答案 0 :(得分:23)
如果您在一台服务器上启动,那么NoSQL的许多优势就会消失。最受欢迎的NoSQL的最大优势是高可用性,停机时间更短。最终的一致性要求也可以带来性能改进。这真的取决于你的需求。
基于文档的 - 如果您的数据非常适合少量数据,那么就是面向文档的数据库。例如,在分类广告网站上,我们将用户,帐户和列表作为核心数据。大部分搜索和显示操作仅针对列表。使用遗留数据库,我们必须进行近40次连接操作,以获取单个列表的数据。使用NoSQL,它只是一个查询。使用NoSQL,我们还可以创建针对嵌套数据的索引,同样在没有连接的情况下查询结果。在这种情况下,我们实际上将数据从SQL镜像到MongoDB以用于搜索和显示(还有其他原因),现在正在进行长期迁移策略。 ElasticSearch,RethinkDB等也是很好的数据库。 RethinkDB实际上对数据采取了非常保守的方法,而ElasticSearch的开箱即用索引是首屈一指的。
键值存储 - 缓存是一个很好的用例,当您运行大多数数据读取的中到高容量网站时,单独一个好的缓存策略可以帮到您单个服务器处理的用户数的4-5倍。键值存储(RocksDB,LevelDB,Redis等)也是Graph数据的非常好的选项,因为单个映射可以使用主题 - 谓词 - 目标值来保存,这对于顶部的图形选项来说非常快。
Columnar - 特别是Cassandra可以用于分配大量的负载,甚至可以进行单值查找。 Cassandra的缩放与使用中的服务器数量非常线性关系。非常适合繁重的读写场景。我发现这对于实时搜索来说不那么有价值,但是当你有非常高负载并且需要分发时非常好。它需要更多的计划,可能不适合您的需求。您可以调整设置以满足您的CAP需求,甚至可以处理框中多个数据中心的分发。注意:大多数应用程序强调 NOT 需要此级别的使用。在您考虑使用HBase / Hadoop或Cassandra的大多数场景中,ElasticSearch可能更适合。
图表 - 我不熟悉图形数据库,因此无法在此处发表评论(除了使用键值存储作为基础选项)。
鉴于您对MongoDB进行了专门评论vs SQL ...即使两者都是自动分片。特别是PostgreSQL在获取非限制数据(JSON / JSONB类型)方面取得了很大进展,更不用说PLV8可以获得的功能,它可能最适合处理负载类型你可能会抛弃具有NoSQL优势的文档存储。碰巧发生倒下的地方是复制,分片和故障转移都是用固定在解决方案中的解决方案。
对于中小负载,分片确实不是最好的方法。大多数场景大多是读取的,所以如果你有3-5个服务器,那么拥有一个副本集你有额外的读取节点通常会更好。在这种情况下,MongoDB很棒,主节点是自动选出的,故障转移非常快。我见过的唯一奇怪的事情是2014年底Azure出现问题,而且只有一台服务器首先出现,其他两台服务器差不多40分钟。通过复制,任何给定的读取请求都可以由单个服务器整体处理。您的数据结构变得更简单,数据丢失的可能性也会降低。
再次在我上面的例子中,对于中等大小的分类广告网站,绝大多数数据都属于一个集合......它会被搜索并从该集合中显示出来。使用此用例,文档存储比结构化/规范化数据工作得更好。存储对象的方式更接近于它们在应用程序中的表示。认知失去了很少,它只是起作用。
事实上,SQL JOIN操作会降低性能,尤其是在跨这些连接聚合数据时。对于单个用户的单个查询,它很好,即使有十几个。当你与成千上万的同时用户进行数十次连接时,它开始崩溃。此时你有几个选择......
缓存 - 缓存始终是一种很好的方法,数据更改的频率越低,方法就越好。这可以是从一组memcache / redis实例到使用MongoDB,RethinkDB或ElasticSearch之类的东西来保存复合记录。这里的挑战归结为更新或使您的缓存数据无效。
迁移 - 将数据迁移到更能代表您需求的数据存储也是一个好主意。如果您需要处理大量写入或非常大量的读取方案,则SQL数据库无法跟上。您可以从不在SQL上处理Facebook或Twitter等。
介于两者之间 - 您需要扩展它取决于您正在做什么以及您的痛点在哪些方面对于特定情况最佳解决方案。许多开发人员和管理员担心将数据分解到多个位置,但这通常是最佳答案。您的分析数据是否真的需要与核心运营数据位于同一位置?那么你的登录需要紧密耦合吗?你在做很多相关的查询吗?这实际上取决于。
未来的个人意见
对我来说,我喜欢SQL提供的安全网。将它作为核心数据的中央存储,它是我的第一选择。我倾向于将RDBMS视为愚蠢的存储,我不喜欢被绑定到给定的平台。我觉得很多人都试图过度规范化他们的数据。通常我会在表中添加一个XML或JSON字段,这样可以存储额外的数据而不会使计划膨胀,特别是如果它不太可能被查询...我会在我的网站中拥有属性存储在这些字段中的应用程序代码中的对象。一个很好的例子可能是付款...如果您目前正在使用一个系统或多个系统(一个用于CC以及Paypal,Google,亚马逊等),那么交易的细节实际上不会影响您的记录,为什么要创建5个表来存储这些详细数据。您甚至可以将JSON用于主存储,并具有从该JSON派生和持久化的计算列,以便在需要时提供更广泛的查询功能和索引。 postgresql和mysql(iirc)等数据库也提供了针对JSON数据的直接索引。
当数据自然适合文档存储时,我会说它...如果你的绝大多数查询是针对单个记录或集合的更好的东西,那么非规范化。将其作为主数据的镜像非常棒。
对于大量写入数据,您需要使用多个系统......这在很大程度上取决于您的需求......您是否需要快速的热查询性能?使用ElasticSearch。你需要绝对大规模的水平刻度,HBase或Cassandra。
这里的关键是不要害怕将它混淆......真的不是一刀切。顺便说一句,我觉得如果PostgreSQL在盒子(开源版本)中提供了一个好的解决方案,即使只是复制和自动故障转移,它们也会比那时的大多数人处于更好的位置。
我没有真正进入,但我觉得我应该提到有许多SaaS解决方案和其他提供混合SQL系统的提供商。您可以在本地针对MySQL / MariaDB进行开发,并在分布式存储群集上部署到具有SQL的系统。我仍然认为HBase或ElasticSearch更适合日志记录和分析数据,但顶级解决方案上的SQL也很引人注目。
答案 1 :(得分:2)
无架构存储(或无架构)。能够修改存储(基本上将新字段添加到记录),而无需修改存储“声明”模式。 RDBMS需要显式声明所述“字段”,并且在保存新的“字段”之前需要对模式进行显式修改。无模式存储引擎允许快速更改应用程序,只需修改应用程序代码以保存额外字段,或重命名字段,或删除字段并完成。
传统的RDBMS民众认为无模式的缺点因为他们认为从长远来看,需要查询存储和处理异构记录(一些有一些字段,一些有其他字段)使其难以处理。但对于一家初创企业来说,无模式是绝对诱人的,因为快速迭代和上市时间是最重要的(通常是正确的)。
答案 2 :(得分:0)
您要求我们假设数据可以放在一台计算机上,或者您的数据库具有有效的自动分片功能。
假设您的SQL数据具有自动分片功能,这意味着您正在谈论运行群集。无论何时运行一组机器,都必须担心容错。
例如,假设您使用的是按应用程序功能分片数据的最简单方法,并将所有用户帐户数据存储在服务器A和服务器B上的产品目录中。
如果服务器A出现故障并且您的用户都无法登录,您的企业是否可以接受?
如果服务器B发生故障并且没有人可以买东西,您的企业是否可以接受?
如果没有,您需要担心设置数据复制和高可用性故障转移。 SQL数据库可行但不愉快或不容易。其他类型的分片策略(密钥,查找服务等)也面临着相同的挑战。
许多NoSQL数据库将自动处理复制和故障转移。有些人会开箱即用,配置很少。从操作的角度来看,这是一个巨大的好处。
完全披露:我是FoundationDB的工程师,这是一个NoSQL数据库,automatically只需很少的配置即可处理分片,复制和故障转移。它还有SQL layer,因此您无需放弃结构化数据。