陈奇网络工作室

后端接口如何提升性能?从MySQL ES HBASE等技术探讨!

本文的内容

显示

1.

1.MySQL查询慢是什么体验?

1.1.

1.1索引

1.1.1.

1.1.1什么原因导致索引无效?

1.1.2.

1.1.2为什么这些原因会导致索引失效?

1.1.2.1 .

功能操作

1.1.2.2 .

隐式转换

1.1.2.3 .

破坏秩序

1.1.3.

1.1.3为什么不将性别领域编入索引?

1.1.4.

1.1.4有哪些简单易行的索引方法?

1.1.5.

1.1.5如何评价MySQL错误的索引选择?

1.2.

1.2相等MDL锁

1.3.

1.3等待冲洗

1.4.

1.4等行锁

1.5.

1.5电流读数

1.6.

1.6大桌场景

1.6.1.

1.6.1子库与子表

1.6.1.1 .

计划

1.6.1.2 .

问题

1.6.2.

1.6.2读写分离

1.6.2.1 .

为什么要分开读和写?

1.6.2.2 .

问题

1.7.

1.7摘要

2.

2.如何评价ElasticSearch

2.1.

2.1我能做什么?

2.2.

2.2专家系统的结构

2.3.

2.3为什么es查询快?

2.3.1.

2.3.1分词后检索

2.3.2.

准确的检索

2.4.

2.4何时使用专家系统

2.4.1.

2.4.1全文检索

2.4.1.1 .

分词

2.4.2.

2.4.2组合查询

2.4.2.1 .

1.ES MySQL

2.4.2.2 .

2.ES HBASE

2.5.

2.5总结

3.

3.HBASE

3.1.

3.1存储结构

3.2.

3.2 OLTP和OLAP

3.3.

3.3行键

3.4.

3.4使用场景

4.

总结

4.1.

推荐阅读

1.MySQL查询慢是什么体验?

谢谢你邀请我。利益是相关的。大部分互联网应用场景都是多读少写,商业逻辑更多分布在文字中。对阅读的要求大概就是要快。那么是什么原因会导致我们完成一个优秀的慢速查询呢?

1.1索引

当数据量不是很大的时候,大部分的慢速查询都可以通过索引来解决,大部分的慢速查询也是因为索引不合理造成的。

MySQL索引是基于B树的。相信这句话在面试中已经背熟了。然后可以问最左边的前缀索引,B树,各种树。

说到最左边的前缀,其实就是组合索引的使用规则。使用合理的组合索引可以有效提高查询速度。为什么?

因为如果查询条件包含在复合索引中,比如存在复合索引(A,B),那么索引是下推的,在找到满足A的记录后,会直接判断B在索引中是否满足,从而减少表返回的次数。同时,如果查询的列恰好包含在复合索引中,则它是一个覆盖索引,不需要返回表。索引规则可能是已知的,并将在实际开发中被创建和使用。问题可能更多的是:为什么建立一个指数很慢?

1.1.1什么原因导致索引无效?

建立索引还是很慢,多半是因为索引无效(未使用),可以通过explain来分析。索引失效的常见原因有:

用在哪里!=或或或或或表达式或函数(左)

Like语句%开始

该字符串不是用“”添加的

索引字段的区分度太差,比如性别。

最左边的前缀不匹配。

1.1.2为什么这些原因会导致索引失效?

如果要MySQL给个理由,还是B树。

功能操作

在查询where=左侧使用表达式或函数时,如果字段A是一个带索引的字符串,并且有一个长度(a)=6的查询,那么不难想象通过将索引树从6传递到A,会在树的第一级迷路。

隐式转换

隐式类型转换和隐式字符编码转换也会导致此问题。

像JOOQ这样的框架一般不会出现隐式类型转换。

链接表的查询中可能会出现隐式字符编码转换,即链接表字段类型相同但字符编码不同。

破坏秩序

至于Like语句以%开头,字符串不加' ' '的原因,MySQL认为对索引字段的操作可能会破坏索引顺序,所以机智优化。

但是,对于区分度太低的字段,如性别,索引会因为这个原因而失败。

1.1.3为什么不将性别领域编入索引?

为什么不索引索引区分度低的字段?瞎猜是低效的,效率确实低,有时候甚至等于没有加法。

对于非聚集索引,返回表。如果有100条数据,在性别字段建立一个索引,扫描51个男性,那么你需要回到表中扫描51行。最好是直接全表扫描。

因此,对于这种情况,InnoDB引擎将放弃使用索引。至于歧视的程度,那就放弃了。当某一类数据占总数的30%左右时,就会放弃使用该字段的索引。有兴趣可以试试。

1.1.4有哪些简单易行的索引方法?

如前所述,大多数缓慢的查询源于索引。如何建立和使用好索引?这里有一些简单的规则。

索引下推:性别字段不适合索引,但是有查询场景怎么办?如果是多条件查询,可以建立联合索引进行优化。

叠加指数:也是联合指数。查询所需的信息已经包含在索引中,因此不会返回到表中。

前缀索引:对于一个字符串,只能在前n位加一个索引,避免不必要的开销。如果真的需要关键字查询,可能交给更合适的比较好,比如ES。

不要对索引字段执行函数运算。

对于某些频繁更新的表或字段,应该考虑索引的维护成本。

1.1.5如何评价MySQL错误的索引选择?

有时候,一个乍看起来很对的指标建立了,但事情并没有按计划进行。就像“为什么XXX有索引,按索引查询还是很慢”。

也许这一刻你应该很自信:我的代码不可能有BUG。MySQL肯定有问题。MySQL可能有问题。

这种情况在构建大量索引和大量查询条件时很常见。不是用你想让它用的那个,而是选了一个分辨率低的,导致扫描次数太多。基本上有两个原因:

信息统计不正确:可以用分析表x重新分析。

优化器误判:可以通过force index强制指定。或者修改语句来指导优化器,添加或删除索引旁路。

但是根据我浅薄的经验,更有可能是你建立了一些不必要的索引。没有人真的觉得MySQL不如自己聪明吧?

除了以上索引原因,还有以下不常见或难以判断的原因。

1.2相等MDL锁

MDL是在MySQL版本5.5中引入的,当在表上执行CRUD时,会自动添加MDL读锁。当改变表结构时,添加MDL写锁。读写锁和写锁是互斥的。

当一个语句持有MDL写锁时,它将阻塞MDL读锁。您可以使用show processlist命令来查看处于等待表元数据锁定状态的语句。

1.3等待冲洗

Flush很快,主要是因为flush命令被其他语句阻塞了,从而阻塞了select。通过show processlist命令查看时,会发现它处于等待表刷新的状态。

1.4等行锁

某些内容持有写锁,尚未提交。

1.5电流读数

InnoDB的默认级别是可重复的。设想一个场景:事务A启动一个事务,事务B也开始执行大量更新。B是第一个提交的,A是当前读数,所以要依次执行undo log,直到找到事务B之前的值。

1.6大桌场景

在没有二次开发的MYSQL中,上亿的表必须算大表。即使在索引和查询层面很好地实现了这种情况,面对频繁的聚集操作也可能出现IO或CPU瓶颈,即使是简单的查询,效率也会下降。

并且Innodb每个B树节点的存储容量为16 KB,理论上可以存储2kw左右的行。此时树高3层。我们知道innodb_buffer_pool用于缓存表和索引。如果索引数据很大,缓存命中率会令人担忧。同时,innodb_buffer_pool使用LRU算法消除页面。如果数据量过大,查询旧的或非热数据可能会挤出热数据。

所以对于大表常见的优化是库表分离,读写分离。

1.6.1子库与子表

计划

是单独的库还是单独的表?这个要具体分析。

如果磁盘或网络有IO瓶颈,就要分库和竖表。

如果是CPU瓶颈,也就是查询效率低,表是横向划分的。

水平意味着拆分数据并将原始数据分散到更多的库表中。

纵向上,数据库根据业务对齐,表根据字段分段。

工具包括sharing-sphere、TDDL和Mycat。首先,我们需要评估子数据库和表的数量,制定分段规则并选择键,然后开发

实际操作中,写问题不大,主要问题是唯一ID生成、分区键查询和容量扩展。

有很多独特的ID方法,比如DB自增量,雪花,号段,大浪GUID算法等等。

非分区键查询通常用映射方法解决,在映射表中使用覆盖索引还是很快的。或者它可以与其他数据库结合使用。

扩展要根据分片的策略来决定,范围分片很简单,随机模数分片会迁移数据。也可以使用范围模划分的模式,先模后范围,可以避免一定程度的数据迁移。

当然,如果分库,还会面临事务一致性、跨库加入等问题。

1.6.2读写分离

为什么要分开读和写?

独立表解决大表的CPU瓶颈,独立库解决IO瓶颈,两者都解决了存储压力。但是查询不一定。

如果落到DB的QPS还是很高,读远大于写,可以考虑读写分离,基于主从模式分担读压力,避免单机高负载,同时保证高可用,实现负载均衡。

问题

主要问题是超期阅读和分配机制。

过期阅读,也就是主从延迟的问题,对于这一点很重要。

分配机制,主或从。可以根据直接代码中的语句类型切换或使用中间件。

1.7摘要

上面列举了MySQL常见查询慢的原因和处理方法,并介绍了处理大数据场景的常用方法。

数据库、表和读写的分离是针对大数据或者并发的场景,也是为了提高系统的稳定性和扩展性。但并不是所有的问题都最适合这种解决方案。

2.如何评价ElasticSearch

如前所述,ES可以用于关键字查询。那我们来说说ES吧

2.1我能做什么?

ES是一个基于Lucene的近实时分布式搜索引擎。使用场景包括全文搜索、NoSQL Json文档数据库、监控日志、数据收集分析等。

对于非数据开发,全文检索和日志应该是常用的。在ES的使用上,常与Logstash、Kibana组合,也成为麋鹿。我们先来看看日志是怎么用的。

下面是我们公司日志系统的一个检索操作:打开Kibana,在Discover页面输入“xxx”等格式查询。

此操作可以替换为:

GET yourIndex/_search{ 'from' 0,' size' 10,' query '{ ' match _ phrase '{ ' log '' XXX ' } } }

你什么意思?在Discover中添加“”和在console中添加match_phrase都表明这是一个短语匹配,这意味着只有那些包含所有搜索词并且与搜索词具有相同位置的文档才会被保留。

2.2专家系统的结构

ES 7.0之前的存储结构是Index-Type-Document,MySQL的对比是database-table-ID(其实这个对比不是那么合理)。Type在7.0之后就被抛弃了,我们暂且以index为表。

在Dev Tools的控制台中,可以通过以下命令查看一些基本信息。您也可以用crul命令替换它。

1.GET /_cat/health?Vpretty:查看集群健康状态2。GET /_cat/shards?v:查看碎片状态3。获取您的index/_ mapping: indexmapping结构4。获取您的index/_ settings: indexsetting结构5。Get/_ cat/indicators?v:查看当前节点的所有索引信息。

重点是映射和设置。映射可以理解为MySQL中表的结构化定义,设置负责控制切片和副本的数量。

下面是一个日志索引下截取的部分映射结构。ES会默认将字符串类型定义为text,并为其定义一个名为keyword的子字段。两者的区别是文本类型会被分割,关键词类型不会被分割。

* * * * * '{ ' mappings '{ ' doc '{ ' properties '{ ' appname '{ ' type '' text '' fields '{ ' keyword '{ ' type '' keyword '' ignore_above' 256 } }

2.3为什么es查询快?

分词是什么意思?看完ES的标引原理,你就懂了。

本节简要介绍了为什么es速度快,以及它可以用在什么地方。现在你可以打开基巴纳的控制台试一试。

如果想接入Java项目,有SpringBoot加持。在ES环境还可以的前提下,完全是开箱即用,只是一个依赖。基本的CRUD支持完全可以。

3.HBASE

HBASE之前已经提到过,HBASE是什么?鉴于篇幅,我在这里简单说一下。

3.1存储结构

像MySQL这样的关系数据库是以行的形式出现的。

(全名)

小学

中学

大学

XX小学

YY高中

HBASE是由柱(实际上是一个柱族)组成的。列存储上的表将变成:

(全名)

学校名称

XX小学

YY高中

下图是HBASE的实际表格模型结构。

行键是主键,按字典顺序排序。时间戳是版本号。Info和area都是柱族,水平切割表格。姓名和年龄称为列,属于一个列簇,可以动态添加。单元格是一个具体的值。

3.2 OLTP和OLAP

数据处理可以大致分为两类:联机事务处理(OLTP)和联机分析处理(OLAP)。

OLTP是传统关系数据库的主要应用,主要是基础和日常事务处理。

OLAP是数据仓库系统的主要应用,支持复杂分析,侧重于决策支持,提供直观易懂的查询结果。

面向列适用于OLAP,面向行适用于联机事务处理(OLTP)。然而,HBASE不是OLAP,它没有交易,它实际上是面向CF的。一般来说,没有多少人把HBASE当成OLAP。

3.3行键

HBASE表的设计依赖于RowKey设计。这是因为HBASE只支持三种查询方法。

1.基于Rowkey 2的单行查询。基于Rowkey 3的范围扫描。全表扫描。

可以看出,HBASE不支持复杂的查询。

3.4使用场景

HBASE不适合实时快速查询。比较适合写密集型的场景,有快速写的能力,而查询对于单个或者小区域的查询还是可以的,当然只能基于rowkey。但是它的性能和可靠性非常高,没有单点故障。

总结

个人认为软件开发是循序渐进的,技术是为项目服务的。合适比新颖和复杂更重要。

如何完成快速查询?最好的办法是先找到自己的bug,解决当前的问题,再创造新的问题。

文中列举的一些方案,对具体实现大多是表面文章。其实无论是MySQL的子表还是ES的业务集成都会面临很多细节和难题,所以工程师要时刻知道这个事情,并且去做。资料来源:https://urlify.cn/JjiIn2.

关于西部数码代理

成都西维数码科技有限公司成立于2002年,注册资金1000万元。其总部位于天府之国成都——,品牌为西部数码代理(www.chenqinet.cn)。深耕IDC行业十余年,在中国拥有北京、广东、郑州、成都、绵阳、香港等多家IDC云计算安全数据中心,在美国拥有海外数据中心。自主研发了虚拟主机、灵活度云服务器、西部数据企业云邮箱等产品,广受用户欢迎。我们始终坚持用户体验至上的价值导向,深度挖掘用户需求。目前,超过100万用户通过我们注册和管理了超过1000万个域名,共有超过50万个网站在我们自研的云主机平台上运行。服务用户有:宝贝回家找子网、四川大学、链家网(北京)科技有限公司、四川省互联网协会、沱牌集团、谭木匠、中铁二局、四川省中国青年旅行社。

我们始终坚持“以人为本、以客为尊、持续创新”的核心价值观,抓住各种发展机遇,不断创新发展理念,不断转变发展方式,不断解决发展难题。随着企业的发展,我们的业务也不断发展为基于云计算的云托管业务、域名注册、域名交易等相关业务。公司从最初的几个员工发展到近200人的精英团队,并在IDC和中国建立了业务。成为拥有多项自主知识产权的国家高新技术企业、获得ICANN和CNNIC双重认证的国际顶级域名注册服务机构、首批获得工信部颁发的国家云服务牌照的企业之一。

后台-系统设置-扩展变量-手机广告位-内容页底部广告位3