商城网站系统建设mysql 收费 网站建设
- 作者: 五速梦信息网
- 时间: 2026年04月20日 09:27
当前位置: 首页 > news >正文
商城网站系统建设,mysql 收费 网站建设,网站制作钱,商务网站建设包含了近年来公司业务迅猛发展#xff0c;数据量爆炸式增长#xff0c;随之而来的的是海量数据查询等带来的挑战#xff0c;我们需要数据量在十亿#xff0c;甚至百亿级别的规模时依然能以秒级甚至毫秒级的速度返回#xff0c;这样的话显然离不开搜索引擎的帮助#xff0c;在搜…近年来公司业务迅猛发展数据量爆炸式增长随之而来的的是海量数据查询等带来的挑战我们需要数据量在十亿甚至百亿级别的规模时依然能以秒级甚至毫秒级的速度返回这样的话显然离不开搜索引擎的帮助在搜索引擎中ESElasticSearch毫无疑问是其中的佼佼者连续多年在 DBRanking 的搜索引擎中评测中排名第一也是绝大多数大公司的首选那么它与传统的 DB 如 MySQL 相比有啥优势呢ES 的数据又是如何生成的数据达到 PB 时又是如何保证 ES 索引数据的实时性以更好地满足业务的需求的呢。
本文会结合我司在 ES 上的实践经验与大家谈谈如何构建准实时索引的一些思路希望对大家有所启发。本文目录如下 为什么要用搜索引擎传统 DB 如 MySQL 不香吗 MySQL 的不足ES 简介 ES 索引数据构建 PB 级的 ES 准实时索引数据构建之道
为什么要用搜索引擎传统 DB 如 MySQL 不香吗
MySQL 的不足
MySQL 架构天生不适合海量数据查询它只适合海量数据存储但无法应对海量数据下各种复杂条件的查询有人说加索引不是可以避免全表扫描提升查询速度吗为啥说它不适合海量数据查询呢有两个原因
*1、*加索引确实可以提升查询速度但在 MySQL 中加多个索引最终在执行 SQL 的时候它只会选择成本最低的那个索引如果没有索引满足搜索条件就会触发全表扫描而且即便你使用了组合索引也要符合最左前缀原则才能命中索引但在海量数据多种查询条件下很有可能不符合最左前缀原则而导致索引失效而且我们知道存储都是需要成本的如果你针对每一种情况都加索引以 innoDB 为例每加一个索引就会创建一颗 B 树如果是海量数据将会增加很大的存储成本之前就有人反馈说他们公司的某个表实际内容的大小才 10G, 而索引大小却有 30G这是多么巨大的成本所以千万不要觉得索引建得越多越好。
*2、*有些查询条件是 MySQL 加索引都解决不了的比如我要查询商品中所有 title 带有「格力空调」的关键词如果你用 MySQL 写会写出如下代码
SELECT * FROM product WHERE title like %格力空调%这样的话无法命中任何索引会触发全表扫描而且你不能指望所有人都能输对他想要的商品是人就会犯错误我们经常会犯类似把「格力空调」记成「格空间」的错误那么 SQL 语句就会变成
SELECT * FROM product WHERE title like %格空调%这种情况下就算你触发了全表扫描也无法查询到任何商品综上所述MySQL 的查询确实能力有限。
ES 简介
与其说上面列的这些点是 MySQL 的不足倒不如说 MySQL 本身就不是为海量数据查询而设计的术业有专攻海量数据查询还得用专门的搜索引擎这其中 ES 是其中当之无愧的王者它是基于 Lucene 引擎构建的开源分布式搜索分析引擎可以提供针对 PB 数据的近实时查询广泛用在全文检索、日志分析、监控分析等场景。
它主要有以下三个特点:
轻松支持各种复杂的查询条件: 它是分布式实时文件存储会把每一个字段都编入索引倒排索引利用高效的倒排索引以及自定义打分、排序能力与丰富的分词插件等能实现任意复杂查询条件下的全文检索需求可扩展性强天然支持分布式存储通过极其简单的配置实现几百上千台服务器的分布式横向扩容轻松处理 PB 级别的结构化或非结构化数据。高可用容灾性能好通过使用主备节点以及故障的自动探测与恢复有力地保障了高可用
我们先用与 MySQL 类比的形式来理解 ES 的一些重要概念 通过类比的形式不难看出 ES 的以下几个概念 1、 MySQL 的数据库DataBase相当于 Index索引数据的逻辑集合ES 的工作主要也是创建索引查询索引。 2、 一个数据库里会有多个表同样的一个 Index 也会有多个 type 3、 一个表会有多行Row同样的一个 Type 也会有多个 Document。 4、 Schema 指定表名表字段是否建立索引等同样的 Mapping 也指定了 Type 字段的处理规则即索引如何建立是否分词分词规则等 5、 在 MySQL 中索引是需要手动创建的而在 ES 一切字段皆可被索引只要在 Mapping 在指定即可
那么 ES 中的索引为何如此高效能在海量数据下达到秒级的效果呢它采用了多种优化手段最主要的原因是它采用了一种叫做倒排索引的方式来生成索引避免了全文档扫描那么什么是倒排索引呢通过文档来查找关键词等数据的我们称为正排索引返之通过关键词来查找文档的形式我们称之为倒排索引假设有以下三个文档Document 要在其中找到含有 comming 的文档如果要正排索引那么要把每个文档的内容拿出来查找是否有此单词毫无疑问这样的话会导致全表扫描那么用倒排索引会怎么查找呢它首先会将每个文档内容进行分词小写化等然后建立每个分词与包含有此分词的文档之前的映射关系如果有多个文档包含此分词那么就会按重要程度即文档的权重通常是用 TF-IDF 给文档打分将文档进行排序于是我们可以得到如下关系 这样的话我们我要查找所有带有 comming 的文档就只需查一次而且这种情况下查询多个单词性能也是很好的只要查询多个条件对应的文档列表再取交集即可极大地提升了查询效率。
画外音这里简化了一些流程实际上还要先根据单词表来定位单词等不过这些流程都很快可以忽略有兴趣的读者可以查阅相关资料了解。
除了倒排索引外ES 的分布式架构也天然适合海量数据查询来看下 ES 的架构 一个 ES 集群由多个 node 节点组成每个 index 是以分片Shardindex 子集的数据存在于多个 node 节点上的这样的话当一个查询请求进来分别在各个 node 查询相应的结果并整合后即可将查询压力分散到多个节点避免了单个节点 CPU磁盘内存等处理能力的不足。
另外当新节点加入后会自动迁移部分分片至新节点实现负载均衡这个功能是 ES 自动完成的对比一个下 MySQL 的分库分表需要开发人员引入 Mycat 等中间件并指定分库分表规则等繁琐的流程是不是一个巨大的进步这也就意味着 ES 有非常强大的水平扩展的能力集群可轻松扩展致几百上千个节点轻松支持 PB 级的数据查询。
当然 ES 的强大不止于此它还采用了比如主备分片提升搜索吞率使用节点故障探测Raft 选主机制等提升了容灾能力等等这些不是本文重点读者可自行查阅总之经过上面的简单总结大家只需要明白一点ES 的分布式架构设计天生支持海量数据查询。
那么 ES 的索引数据index如何生成的呢接下来我们一起来看看本文的重点
如何构建 ES 索引
要构建 ES 索引数据首先得有数据源一般我们会使用 MySQL 作为数据源你可以直接从 MySQL 中取数据然后再写入 ES但这种方式由于直接调用了线上的数据库查询可能会对线上业务造成影响比如考虑这样的一个场景
在电商 APP 里用的最多的业务场景想必是用户输入关键词来查询相对应的商品了那么商品会有哪些信息呢一个商品会有多个 skusku 即同一个商品下不同规格的品类比如苹果手机有 iPhone 6, iPhone 6s等,会有其基本属性如价格标题等商品会有分类居家服饰等品牌库存等为了保证表设计的合理性我们会设计几张表来存储这些属性假设有 product_skusku 表, product_property基本属性表,sku_stock库存表product_category分类表这几张表那么为了在商品展示列表中展示所有这些信息就必须把这些表进行 join然后再写入 ES这样查询的时候就会在 ES 中获取所有的商品信息了。 这种方案由于直接在 MySQL 中执行 join 操作在商品达到千万级时会对线上的 DB 服务产生极大的性能影响所以显然不可行那该怎么生成中间表呢既然直接在 MySQL 中操作不可行能否把 MySQL 中的数据同步到另一个地方再做生成中间表的操作呢也就是加一个中间层进行处理这样就避免了对线上 DB 的直接操作说到这相信大家又会对计算机界的名言有进一步的体会没有什么是加一个中间层不能解决的如果有那就再加一层。
这个中间层就是 hive 什么是 hive hive 是基于 Hadoop 的一个数据仓库工具用来进行数据提取、转化、加载这是一种可以存储、查询和分析存储在 Hadoop 中的大规模数据的机制它的意义就是把好写的 hive 的 sql 转换为复杂难写的 map-reduce 程序map-reduce 是专门用于用于大规模数据集大于1TB的并行运算编程模型也就是说如果数据量大的话通过把 MySQL 的数据同步到 hive再由 hive 来生成上述的 product_tmp 中间表能极大的提升性能。hive 生成临时表存储在 hbase一个分布式的、面向列的开源数据库 中生成后会定时触发 dump task 调用索引程序然后索引程序主要从 hbase 中读入全量数据进行业务数据处理并刷新到 es 索引中整个流程如下 这样构建索引看似很美好但我们需要知道的是首先 hive 执行 join 任务是非常耗时的在我们的生产场景上由于数据量高达几千万执行 join 任务通常需要几十分钟从执行 join 任务到最终更新至 ES 整个流程常常需要至少半小时以上如果这期间商品的价格库存上线状态如被下架等重要字段发生了变更索引是无法更新的这样会对用户体验产生极大影响优化前我们经常会看到通过 ES 搜索出的中有状态是上线但实际是下架的产品严重影响用户体验那么怎么解决呢有一种可行的方案建立宽表
既然我们发现 hive join 是性能的主要瓶颈那么能否规避掉这个流程呢能否在 MySQL 中将 product_skuproduct_propertysku_stock 等表组合成一个大表我们称其为宽表 这样在每一行中商品涉及到的的数据都有了所以将 MySQL 同步到 hive 后hive 就不需要再执行耗时的 join 操作了极大的提升了整体的处理时间从 hive 同步 MySQL 再到 dump 到 ES 索引中从原来的半小时以上降低到了几分钟以内看起来确实不错但几分钟的索引延迟依然是无法接受的。 为什么 hive 无法做到实时导入索引 因为 hive 构建在基于静态批处理的Hadoop 之上Hadoop 通常都有较高的延迟并且在作业提交和调度的时候需要大量的开销。因此hive 并不能够在大规模数据集上实现低延迟快速的查询等操作再且千万级别的数据全量从索引程序导入到 ES 集群至少也是分钟级。
另外引入了宽表它的维护也成了一个新问题设想 sku 库存变了产品下架了价格调整了那么除了修改原表sku_stock,product_categry 等表记录之外还要将所有原表变更到的记录对应到宽表中的所有记录也都更新一遍这对代码的维护是个噩梦因为你需要在所有商品相关的表变更的地方紧接着着变更宽表的逻辑与宽表的变更逻辑变更紧藕合
PB 级的 ES 准实时索引构建之道
该如何解决呢仔细观察上面两个问题其实都是同一个问题如果我们能实时监听到 db 的字段变更再将变更的内容实时同步到 ES 和宽表中不就解决了我们的问题了。
怎么才能实时监听到表字段的变更呢 答案binlog 来一起复习下 MySQL 的主从同步原理 MySQL master 将数据变更写入二进制日志( binary log, 其中记录叫做二进制日志事件binary log events可以通过 show binlog events 进行查看)MySQL slave 将 master 的 binary log events 拷贝到它的中继日志(relay log)MySQL slave 重放 relay log 中事件将数据变更反映它自己的数据
可以看到主从复制的原理关键是 Master 和 Slave 遵循了一套协议才能实时监听 binlog 日志来更新 slave 的表数据那我们能不能也开发一个遵循这套协议的组件当组件作为 Slave 来获取 binlog 日志进而实时监听表字段变更呢阿里的开源项目 Canal 就是这个干的它的工作原理如下:
canal 模拟 MySQL slave 的交互协议伪装自己为 MySQL slave 向 MySQL master 发送dump 协议MySQL master 收到 dump 请求开始推送 binary log 给 slave (即 canal )canal 解析 binary log 对象(原始为 byte 流) 这样的话通过 canal 就能获取 binlog 日志了当然 canal 只是获取接收了 master 过来的 binlog还要对 binlog 进行解析过滤处理等另外如果我们只对某些表的字段感兴趣该如何配置获取到 binlog 后要传给谁? 这些都需要一个统一的管理组件阿里的 otter 就是干这件事的。 什么是 otter Otter 是由阿里提供的基于数据库增量日志解析准实时同步到本机房或异地机房 MySQL 数据库的一个分布式数据库同步系统它的整体架构如下 注以上是我司根据 otter 改造后的业务架构与原版 otter 稍有不同不过大同小异
主要工作流程如下
在 Manager 配置好 zk要监听的表 负责监听表的节点然后将配置同步到 Nodes 中node 启动后则其 canal 会监听 binlog然后经过 SselectEextractT(transform)L(load) 四个阶段后数据发送到 MQ然后业务就可以订阅 MQ 消息来做相关的逻辑处理了
画外音zookeeper 主要协调节点间的工作如在跨机房数据同步时可能要从 A 机房的节点将数据同步到 B 机房的节点要用 zookeeper 来协调
大家应该注意到了node 中有 SETL 四个阶段它们的主要作用如下 Select 阶段: 为解决数据来源的差异性比如接入 canal 获取增量数据也可以接入其他系统获取其他数据等。Extract阶段: 组装数据,针对多种数据来源mysql,oracle,store,file等,进行数据组装和过滤。Transform 阶段: 数据提取转换过程把数据转换成目标数据源要求的类型Load 阶段: 数据载入,把数据载入到目标端如写入迁移后的数据库 MQES 等
以上这套基于阿里 otter 改造后的数据服务我们将它称为 DTSData Transfer Service即数据传输服务。
搭建这套服务后我们就可以通过订阅 MQ 来实时写入 ES 让索引实时更新了而且也可以通过订阅 MQ 来实现宽表字段的更新解决了上文中所说的宽表字段更新与原表紧藕合的问题基于 DTS 服务的索引改进架构如下: 注意「build 数据」这一模块对实时索引更新是透明的这个模块主要用在更新或插入 MySQL 宽表因为对于宽表来说它是几个表数据的并集所以并不是监听到哪个字段变更就更新哪个它要把所有商品涉及到的所有表数据拉回来再更新到宽表中。
于是通过 MySQL 宽表全量更新基于 DTS 的实时索引更新我们很好地解决了索引延迟的问题能达到秒级的 ES 索引更新
这里有几个问题可能大家比较关心我简单列一下 需要订阅哪些字段 对于 MySQL 宽表来说由于它要保存商品的完整信息所以它需要订阅所有字段但是对于红框中的实时索引更新而言它只需要订阅库存价格等字段因为这些字段如果不及时更新会对销量产生极大的影响所以我们实时索引只关注这些敏感字段即可。 有了实时索引更新还需要全量索引更新吗 需要主要有两个原因
实时更新依赖消息机制无法百分百保证数据完整性需要全量更新来支持这种情况很少而且消息积压等会有告警所以我们一天只会执行一次全量索引更新索引集群异常或崩溃后能快速重建索引 全量索引更新的数据会覆盖实时索引吗 会设想这样一种场景你在某一时刻触发了实时索引然后此时全量索引还在执行中还未执行到实时索引更新的那条记录这样在的话当全量索引执行完之后就会把之前实时索引更新的数据给覆盖掉针对这种情况一种可行的处理方式是如果全量索引是在构建中实时索引更新消息可以延迟处理等全量更新结束后再消费。也正因为这个原因全量索引我们一般会在凌晨执行由于是业务低峰期最大可能规避了此类问题。
总结
本文简单总结了我司在 PB 级数据下构建实时 ES 索引的一些思路希望对大家有所帮助文章只是简单提到了 EScanalotter 等阿里中间件的应用但未对这些中间件的详细配置原理等未作过多介绍这些中间件的设计非常值得我们好好研究下比如 ES 为了提高搜索效率、优化存储空间做了很多工作再比如 canal 如何做高可用otter 实现异地跨机房同步的原理等建议感兴趣的读者可以之后好好研究一番相信你会受益匪浅。
巨人的肩膀
Elasticsearch简介及与MySQL查询原理对比https://www.jianshu.com/p/116cdf5836f2https://www.cnblogs.com/zhjh256/p/9261725.htmlotter安装之otter-node安装单机多节点安装https://blog.csdn.net/u014642915/article/details/96500957MySQL和Lucene索引对比分析: https://developer.aliyun.com/article/5048110 分钟快速入门海量数据搜索分析引擎 Elasticearch: https://www.modb.pro/db/29806ElasticSearch和Mysql查询原理分析与对比:https://www.pianshen.com/article/4254917942/带你走进神一样的Elasticsearch索引机制:https://zhuanlan.zhihu.com/p/137574234
- 上一篇: 商城网站是免费开吗C 如何做简易网站
- 下一篇: 商城网站要怎样建设培训班网页设计
相关文章
-
商城网站是免费开吗C 如何做简易网站
商城网站是免费开吗C 如何做简易网站
- 技术栈
- 2026年04月20日
-
商城网站设计费用wordpress直接访问站点
商城网站设计费用wordpress直接访问站点
- 技术栈
- 2026年04月20日
-
商城网站设计定制在线简历制作
商城网站设计定制在线简历制作
- 技术栈
- 2026年04月20日
-
商城网站要怎样建设培训班网页设计
商城网站要怎样建设培训班网页设计
- 技术栈
- 2026年04月20日
-
商城网站要怎样设计wordpress 群晖设置
商城网站要怎样设计wordpress 群晖设置
- 技术栈
- 2026年04月20日
-
商城网站源码dede宿迁网站建设推广公司
商城网站源码dede宿迁网站建设推广公司
- 技术栈
- 2026年04月20日
