hil*_*lel 35 sql bigdata in-memory-database apache-spark apache-spark-sql
引用Spark DataFrames,Datasets和SQL手册:
Spark中还没有包含少数Hive优化.由于Spark SQL的内存计算模型,其中一些(如索引)不太重要.其他版本用于将来的Spark SQL版本.
作为Spark的新手,我有点困惑,原因有两个:
Spark SQL旨在处理大数据,至少在我的用例中,数据大小远远超过可用内存的大小.假设这并不罕见,"Spark SQL的内存计算模型"是什么意思?Spark SQL是否仅适用于数据适合内存的情况?
即使假设数据适合内存,对非常大的数据集进行全扫描也需要很长时间.我在内存数据库中读取了这个反对索引的论点,但我并不相信.那里的例子讨论了一个10,000,000记录表的扫描,但这不是真正的大数据.扫描具有数十亿条记录的表可能导致"SELECT x WHERE y = z"类型的简单查询永远不会立即返回.
我理解索引有诸如较慢的INSERT/UPDATE,空间要求等缺点.但在我的用例中,我首先处理并将大批数据加载到Spark SQL中,然后将这些数据作为一个整体进行探索,而无需进一步修改.Spark SQL对于初始分布式处理和数据加载很有用,但缺乏索引使得交互式探索比我预期的更慢,更麻烦.
我想知道为什么Spark SQL团队认为索引不重要到它的路线图之外的程度.是否有不同的使用模式可以提供索引的好处,而无需独立实现等效的东西?
zer*_*323 35
索引输入数据
索引分布式数据结构:
可以说,某些形式的索引结构确实存在于Spark生态系统中.最值得注意的是,Databricks 在其平台上提供了数据跳过索引.
其他项目,如Succinct(今天大多不活跃)采用不同的方法,并使用高级压缩技术和随机访问支持.
当然,这提出了一个问题 - 如果需要有效的随机访问,为什么不使用从一开始就设计为数据库的系统.有很多选择,包括至少一些由Apache基金会维护的选择.与此同时,Spark作为一个项目不断发展,您使用的报价可能无法完全反映Spark未来的发展方向.
Dav*_*fin 15
一般来说,索引的效用充其量是有问题的.相反,数据分区更重要.它们是非常不同的东西,并且仅仅因为您选择的数据库支持索引并不意味着它们在Spark试图做的事情中有意义.它与"在记忆中"无关.
那么什么是指数呢?
回到永久存储是疯狂昂贵(而不是基本免费)的日子,关系数据库系统都是关于最小化永久存储的使用.必要时,关系模型将记录分成多个部分 - 规范化数据 - 并将它们存储在不同的位置.要阅读客户记录,也许你会阅读一张customer
桌子,一张customerType
桌子,从表格中取出几个条目address
等.如果你有一个解决方案要求你阅读整个表格以找到你想要的东西,这是非常昂贵的,因为你必须扫描这么多表.
但这不是唯一的做事方式.如果您不需要具有固定宽度的列,则可以将整个数据集存储在一个位置.您无需在一堆表上执行全表扫描,而只需在单个表上执行此操作.而且这并不像你想象的那么糟糕,特别是如果你可以对数据进行分区.
40年后,物理定律发生了变化.硬盘随机读/写速度和线性读/写速度有很大差异.基本上每个磁盘可以进行350次磁头移动.(或多或少,但这是一个很好的平均数.)另一方面,单个磁盘驱动器可以读取大约每秒100 MB.那是什么意思?
算一算并考虑一下 - 这意味着如果每个磁盘头的移动读数低于300KB,则会限制驱动器的吞吐量.
Seriouusly.想一想.
索引的目标是允许您将磁盘头移动到所需磁盘上的精确位置,然后只读取该记录 - 比如address
记录中加入的customer
记录.我说,那没用.
如果我正在设计一个基于现代物理学的索引,它只需要让我在目标数据块的100KB左右(假设我的数据已经以大块的方式布局 - 但我们无论如何都在谈论理论) .基于上面的数字,比这更精确只是浪费.
现在回到标准化的表格设计.假设一条customer
记录实际上分为5个表中的6行.6总磁盘头移动(我假设索引缓存在内存中,因此没有磁盘移动).这意味着我可以读取1.8 MB的线性/非标准化客户记录,并且效率也一样高.
客户历史怎么样?假设我不想只看到客户今天的样子 - 想象一下,我想要完整的历史记录,还是历史的一部分?将上面的所有内容乘以10或20即可得到图片.
什么比索引更好的是数据分区 - 确保所有客户记录最终都在一个分区中.通过单磁盘头移动,我可以读取整个客户历史记录.一个磁头移动.
再次告诉我你为什么要索引.
索引vs ___?
不要误会我的意思 - 你的搜索"预先烹饪"是有价值的.但物理定律提出了比传统指数更好的方法.而不是将客户记录存储在一个位置,并创建指向它的指针 - 索引 - 为什么不将记录存储在多个位置?
请记住,磁盘空间基本上是免费的.而不是试图最小化我们使用的存储量 - 关系模型的过时工件 - 只需将您的磁盘用作搜索缓存.
如果您认为某人希望按地理位置和销售代表查看客户,则以优化这些搜索的方式存储客户记录的多个副本.就像我说的那样,使用像内存缓存一样的磁盘.不是通过将不同的持久数据组合在一起来构建内存缓存,而是构建持久数据以镜像内存缓存,因此您只需要读取它.事实上,甚至不想将其存储在内存中 - 只需在每次需要时直接从磁盘读取它.
如果您认为这听起来很疯狂,请考虑这一点 - 如果您将其缓存在内存中,您可能会将其缓存两次.您的操作系统/驱动器控制器可能使用主内存作为缓存.不要打扰缓存数据,因为其他人已经是!
但我离题了......
简而言之,Spark绝对支持正确的索引类型 - 从原始数据创建复杂的派生数据以使未来使用更加高效的能力.它只是不按你想要的方式去做.
归档时间: |
|
查看次数: |
10070 次 |
最近记录: |