关于大型网站技术演进的思考(六)--存储的瓶颈(6)

news/2024/5/20 15:47:52/文章来源:https://blog.csdn.net/weixin_34194551/article/details/92673020

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

在讲数据库水平拆分时候,我列出了水平拆分数据库需要解决的两个难题,它们分别是主键的设计问题和单表查询的问题,主键问题前文已经做了比较详细的讲述了,但是第二个问题我没有讲述,今天我将会讲讲如何解决数据表被水平拆分后的单表查询问题。

  要解决数据表被水平拆分后的单表查询问题,我们首先要回到问题的源头,我们为什么需要将数据库的表进行水平拆分。下面我们来推导下我们最终下定决心做水平拆分表的演进过程,具体如下:

  第一个演进过程:进行了读写分离的表在数据增长后需要进行水平拆分吗?回答这个疑问我们首先要想想进行读写分离操作的表真的是因为数据量大吗?其实是否定的。最基本的读写分离的目的是为了解决数据库的某张表读写比率严重失衡的问题, 举个例子,有一张表每天会增加1万条数据,也就是说我们的系统每天会向这张表做1万次写的操作,当然也有可能我们还会更新或者删除这张表的某些已有的记 录,这些操作我们把它归并到写操作,那么这张表一天我们随意定义个估值吧2万5千次写操作,其实这种表的数据量并不大,一年下来也就新增的几百万条数据, 一个大型的商业级别的关系数据库,当我们为表建立好索引和分区后,查询几百万条数据它的效率并不低,这么说来查询的效率问题还不一定是读写分离的源头。其 实啊,这张表除了写操作每天还承受的读操作可能会是10万,20万甚至更高,这个时候问题来了,像oracle和mysql这样鼎鼎大名的关系数据库默认 的最大连接数是100,一般上了生产环境我们可能会设置为150或者200,这些连接数已经到了这些关系数据库的最大极限了,如果再加以提升,数据库性能 会严重下降,最终很有可能导致数据库由于压力过大而变成了一个巨锁,最终导致系统发生503的错误,如是我们就会想到采用读写分离方案,将数据库的读操作 迁移到专门的读库里,如果系统的负载指标和我列举的例子相仿,那么迁移的读库甚至不用做什么垂直拆分就能满足实际的业务需求,因为我们的目的只是为了减轻 数据库的连接压力。

  第二个演进过程: 随着公司业务的不断增长,系统的运行的压力也越来越大了,我们已经了解了系统的第一个瓶颈是从存储开始了,如是我们开始谈论方案如何解决存储的问题,这时 我们发现我们已经做了读写分离,也使用了缓存,甚至连搜索技术也用上了,那么下个阶段就是垂直拆分了,垂直拆分很简单就是把表从数据库里拆出来,单独建库 建表,但是这种直截了当的方案想想就能感到这样的做法似乎没有打中系统的痛点,那么系统的痛点到底是什么呢?根据数据库本身的特性,我们会发现痛点主要是 三个方面组成:

  第一个方面:数据库的连接数的限制。 原库的某些表可能承担数据库80%的连接,极端下甚至可以超过90%的连接,而且这些表的业务操作十分的频繁,当其他小众业务的表需要进行操作时候,搞不 好因为连接数被全部占用而不得不排队等待空闲连接的出现,那么这个时候我们就会考虑把这张表做垂直拆分,这样就减轻了原数据库连接的压力,使得数据库连接 负载变得比较均衡。

  第二个方面是数据库的读操作,第三个方面是数据库的写操作, 虽然把读和写分成两个方面,但是这两个方面在我们做垂直拆分时候要结合起来考虑。首先我们要分析下数据库的写操作,单独的写操作效率都是很高的,不管我们 的写是单条记录的写操作,还是批量的写操作,这些写操作的数据量就是我们要去写的数据的大小,因此控制写的数据量的大小是一件很容易很天然的操作,所以这 些操作不会造成数据库太大负担,详细点的话,对于数据库而言,新增操作无非是在原来数据后面追加些记录,而修改操作或者删除操作一般都是通过建立了高效索 引的字段来定位数据后再进行的操作,因此它的性能也是非常高的。而读操作看起来比写操作简单(例如:读操作不存在像事务这些乌七八糟因素的干扰),但是当 读操作面对海量数据时候就严重挑战着数据库和硬盘的极限能力,因此读操作很容易产生瓶颈问题,而且这个瓶颈不管问题表是否读写失衡都会面临的。前文里我详 细列举了一个交易表设计的案例,其中我们可以看到数据库垂直拆分在实际应用里的运用,在例子里我们首先根据业务特点将交易表分成了实时交易表和历史交易 表,这个做法其实就是将原交易表的读和写进行分离,但是这种分离和纯粹的读写分离相比会更加有深意,这个深意就是拆分实时和历史交易表也就是在分拆原表的 读写操作的关联性,换句话说,如果我们不这么做的话,那么交易表的每次写和每次读几乎等价,这样我们没法单独解决读的性能问题,分出了历史交易表后我们再 对历史交易表来做读的优化,那么这也不会影响到写操作,这样把问题的复杂度给降低了。在案例里我们对历史交易表进行了业务级别的水平拆分,但是这个拆分是 以如何提升读的效率进行的,因此前文讲到的水平拆分里主键设计方案基本上派不上用场,因为这两种水平拆分的出发点是不同的,那么使用的手段和达到效果也将 不一样。

  由上所述,我们可以把数据库的水平拆分重新定义下,我在这几篇文章里一直讲述的水平拆分本质是从数据库技术来定义的,我把它们称为狭义的水平拆分,与狭义相对的就是广义的水平拆分,例如上文例子里把交易表根据业务特性分为实时交易表和历史交易表,这种行为也是一种水平拆分,但是这个拆分不会遵守我前面讲到主键设计方案,但是它的确达到水平拆分的目的,所以这样的水平拆分就属于广义的水平拆分了。

  第三个演进过程:到了三个演进过程我们就会考虑到真正的水平拆分了,也就是上面提到的狭义的水平拆分了,狭义的水平拆分执行的理由有两个,一个那就是数据量太大了,另一个是数据表的读写的关联性很难进行拆分了, 这点和垂直拆分有所不同,做垂直拆分的考虑不一定是因为数据量过大,例如某种表数据量不大,但是负载过重,很容易让数据库达到连接的极限值,我们也会采取 垂直拆分手段来解决问题,此外,我们想减轻写操作和读操作的关联性,从而能单独对有瓶颈的写操作或读操作做优化设计,那么我们也会考虑到垂直拆分,当然数 据量实在是太大的表我们想优化,首先也会考虑到垂直拆分,因为垂直拆分是针对海量数据优化的起始手段,但是垂直拆分可不一定能解决海量数据的问题。

  狭义水平 拆分的使用的前提是因为数据量太大,到底多大了,我们举个例子来说明下,假如某个电商平台一天的交易笔数有2亿笔,我们用来存储数据的关系数据库单表记录 到了5千万条后,查询性能就会严重下降,那么如果我们把这两亿条数据全部存进这个数据库,那么随着数据的累积,实时交易查询基本已经没法正常完成了,这个 时候我们就得考虑把实时交易表进行狭义的水平拆分,狭义的水平拆分首先碰到的难点就是主键设计的问题,主键设计问题也就说明狭义水平拆分其实解决的是海量 数据写的问题,如果这张表读操作很少,或者基本没有,这个水平拆分是很好设计的,但是一张表只写不读,对于作为业务系统的后台数据库那基本是非常罕见 的,。

  前文讲到 的主键设计方案其实基本没有什么业务上的意义,它解决的主要问题是让写入的数据分布均匀,从而能合理使用存储资源,但是这个合理分布式存储资源却会给查询 操作带来极大的问题,甚至有时可以说狭义水平拆分后数据查询变得困难就是由这种看起来合理的主键设计方案所致。

  我们还是 以实时交易表的实例来说明问题,一个电商平台下会接入很多不同的商户,但是不同的商户每天产生的交易量是不同,也就是说商户的维度会让我们使交易数据变得 严重的不均衡,可能电商平台下不到5%的商户完成了全天交易量的80%,而其他95%的商户仅仅完成20%的交易量,但是作为业务系统的数据表,进行读操 作首先被限制和约束的条件就是商户号,如果要为我们设计的实时交易表进行狭义的水平拆分,做拆分前我们要明确这个拆分是由交易量大的少量商户所致,而不是 全部的商户所致的。如果按照均匀分布主键的设计方案,不加商户区分的分布数据,那么就会发生产生少量交易数据的商户的查询行为也要承受交易量大的商户数据 的影响,而能产生大量交易数据的商户也没有因为自己的贡献度而得到应有的高级服务,碰到这个问题其实非常好解决,就是在做狭义水平拆分前,我们先做一次广 义的水平拆分,把交易量大的商户交易和交易量小的商户交易拆分出来,交易量小的商户用一张表记录,这样交易量小的商户也会很happy的查询出需要的数 据,心里也是美滋滋的。接下来我们就要对交易量大的商户的交易表开始做狭义的水平拆分了,为这些重点商户做专门的定制化服务。

  做狭义水 平拆分前,我们有个问题需要过一下,在狭义水平拆分前我们需要先做一下广义的水平拆分吗?这个我这里不好说,具体要看实际的业务场景,但是针对我列举的实 时交易的例子而言,我觉得没那个必要,因此拆分出的重点商户交易量本来就很大,每个都在挑战数据库读能力的极限,更重要的是实时交易数据的时间粒度已经很 小了,再去做广义水平拆分难度很大,而且很难做好,所以这个时候我们还是直接使用狭义的水平拆分。拆分完毕后我们就要解决查询问题了。

  做实时查询的标准做法就是分页查询了,在讲述如何解决分页查询前,我们看看我们在淘宝里搜索【衣服】这个条件的分页情况,如下图所示:

 

 

  我们看到 一共才100页,淘宝上衣服的商品最多了,居然搜索出来的总页数只有100页,这是不是在挑战我们的常识啊,淘宝的这个做法也给我们在实现水平拆分后如何 做分页查询一种启迪。要说明这个启迪前我们首先要看看传统的分页是如何做的,传统分页的做法是首先使用select count(1) form table这样的语句查询出需要查询数据的总数,然后再根据每页显示的记录条数,查询出需要显示的记录,然后页面根据记录总数,每页的条数,和查询的结果 来完成分页查询。回到我们的交易表实例里,有一个重要商户在做实时交易查询,可是这个时候该商户已经产生了1千万笔交易了,假如每页显示10条,记录那么 我们就要分成100万页,这要是真显示在页面上,绝对能让我们这些开发人员像哥伦布发现新大陆那样惊奇,反正我见过的最多分页也就是200多页,还是在百 度搜索发现的。其实当数据库一张表的数据量非常大的时候,select的count查询效率就非常低下,这个查询有时也会近似个全表检索,所以count 查询还没结束我们就会失去等待结果的耐心了,更不要是说等把数据查询出来了,所以这个时候我们可以学习下淘宝的做法,当商户第一次查询我们准许他查询有限 的数据。我自己所做的一个项目的做法就是这样的,当某个商户的交易量实在是很大时候我们其实不会计算数据的总笔数,而是一次性查询出1000条数据,这 1000条数据查询出来后存入到缓存里,页面则只分100页,当用户一定要查询100页后的数据,我们再去追加查询,不过实践下来,商户基本很少会查询 100页后的数据,常常看了5,6页就会停止查询了。不过商户也时常会有查询全部数据的需求,但是商户有这种需求的目的也不是想在分页查询里看的,一般都 是为了比对数据使用的,这个时候我们一般是提供一个发起下载查询全部交易的功能页面,商户根据自己的条件先发起这样的需求,然后我们系统会在后台单独起个 线程查询出全部数据,生成一个固定格式的文件,最后通过一些有效手段通知商户数据生成好了,让商户下载文件即可。

  对于进行 了狭义水平拆分的表做分页查询我们通常都不会是全表查询,而是抽取全局的数据的一部分结果呈现给用户,这个做法其实和很多市场调查的方式类似,市场调查我 们通常是找一些样本采集相关数据,通过分析这些样本数据推导出全局的一个发展趋势,那么这些样本选择的合理性就和最终的结论有很大关系,回到狭义水平拆分 的表做分页查询,我们为了及时满足用户需求,我们只是取出了全部数据中的一部分,但是这一部分数据是否满足用户的需求,这个问题是很有学问的,如果是交易 表,我们往往是按时间先后顺序查询部分数据,所以这里其实使用到了一个时间的维度,其他业务的表可能这个维度会不一样,但肯定是有个维度约束我们到底返回 那些部分的数据。这个维度可以用一个专有的名词指代那就是排序,具体点就是要那个字段进行升序还是降序查询,看到这里肯定有人会有异议,那就是这种抽样式 的查询,肯定会导致查询的命中率的问题,即查出来的数据不一定全部都是我们要的,其实要想让数据排序正确,最好就是做全量排序,但是一到全量排序那就是全 表查询,做海量数据的全表排序查询对于分页这种场景是无法完成的。回到淘宝的例子,我们相信淘宝肯定没有返回全部数据,而是抽取了部分数据分页,也就是淘 宝查询时候加入了维度,每个淘宝的店家都希望自己的商户放在搜索的前列,那么淘宝就可以让商家掏钱,付了钱以后淘宝改变下商家在这个维度里的权重,那么商 家的商品就可以排名靠前了。

  狭义水平 拆分的本身对排序也有很大的影响,水平拆分后我们一个分页查询可能要从不同数据库不同的物理表里去取数据,单表下我们可以先通过数据库的排序算法得到一定 的数据,但是局部的排序到了全局可能就不正确了,这个又该怎么办了?其实由上面内容我们可以知道要满足对海量数据的所有查询限制是非常难的,时常是根本就 无法满足,我们只能做到尽量多满足些查询限制,也就是海量查询只能做到尽量接近查询限制的条件,而很难完全满足,这个时候我前面提到的主键分布方案就能起 到作用了,我们在设计狭义水平拆分表主键分布时候是尽量保持数据分布均衡,那么如果我们查询要从多张不同物理表里取的时候,例如我们要查1000条数据, 而狭义水平拆分出了两个物理数据库,那么我们就可以每个数据库查询500条,然后在服务层归并成1000条数据,在服务层排序,这种场景下如果我们的主键 设计时候还包含点业务意义,那么这个排序的精确度就会得到很大提升。假如用户对排序不敏感,那就更好做了,分页时候如果每页规定显示10条,我们可以把 10条数据平均分配给两个数据库,也就是显示10条A库的数据,再显示5条B库的数据。

  看到这里 有些细心的朋友可能还会有疑问,那就是居然排序是分页查询的痛点,那么我们可以不用数据库查询,而使用搜索技术啊,NoSql数据库啊,的确这些技术可以 更好的解决分页问题,但是关系数据库过渡到搜索引擎和NoSql数据库首先需要我们转化数据,而狭义的水平拆分的数据表本身数据量很大,这个转化过程我们 是没法快速完成的,如果我们对延时容忍度那么高,其实我们就没必要去做数据库的狭义水平拆分了。这个问题反过来说明了使用狭义拆分数据表的业务场景,那就 是:针对数据量很大的表同时该表的读写的关联性是没法有效拆分的

  最后我要 讲的是,如果系统到了狭义水平拆分都没法解决时候,我们就要抛弃传统的关系数据方案了,将该业务全部使用NoSql数据库解决或者像很多大型互联网公司那 样,改写开源的mysql数据库。文章写道这里,我还是想说一个观点,如果一个系统有很强烈需求去做狭义的水平拆分,那么这个公司的某个业务那肯定是非常 的大了,所以啊,这个方案以公司为单位应该有点小众了。

  好了,今天写到这里,祝大家晚安,生活愉快。


转载于:https://my.oschina.net/huangcongcong/blog/513366

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_717524.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

keepalived+LVS实现网站负载均衡和HA

如上图所示,102和103是内网nginx服务器,100和101是边界LB,clinet是1,这个实验是为了实现在LB上虚拟出一个VIP,client通过访问该VIP,来动态负载到两台内网nginx服务器上面来。流量的来回,都需要经…

大型网站的HTTPS实践一:HTTPS协议和原理一

1 前言百度已经于近日上线了全站 HTTPS 的安全搜索,默认会将 HTTP 请求跳转成 HTTPS。本文重点介绍 HTTPS 协议, 并简单介绍部署全站 HTTPS 的意义。2 HTTPS 协议概述HTTPS 可以认为是 HTTP TLS。HTTP 协议大家耳熟能详了,目前大部分 WEB 应用和网站都是…

在github搭建个人网站

2019独角兽企业重金招聘Python工程师标准>>> 在github搭建个人网站 标签:github [TOC] 先搜篇中文博客了解下流程,再根据下面的官方文档按顺序看一遍就差不多了。 这里不得不吐槽windows太垃圾了,linux下三行指令解决的问题&#…

揭秘SEO快排原理

很多的SEOer每天绝大部分的时间都耗在撰写原创文章/伪原创文章以及发布软文外链,更换行业不相关的友链,年复一年,日复一日,关键词的排名依旧排在100名开外-20名以内,心里很是着急。看看同行竞争对手的网站,…

某搜索网站HR校园招聘被怼引争议,为啥危机偏爱30+人士?

豆瓣上有个热帖,网友去参加校园招聘会,某搜索网站HR表示,他们公司平均年龄都很年轻、很阳光,于是有人怼了句“那你们公司年龄大的都去哪里了?”,HR直接懵了。 是啊!年纪大的去哪里了&#xff1f…

如何将自己的网站分享到QQ空间,微信,微博等等。

2019独角兽企业重金招聘Python工程师标准>>> 逛一些网站的时候经常会看到右侧挂个分享栏,让用户把自己的站分享到qq空间,微信等等,所以自己也研究了下,把他加到了自己的网站上,喜欢的可以先看看效果&#x…

草根站长这一年用血的教训换来的SEO终极算法

导读:标题言过其实,但是草根站长都有自己真实的故事。我2015年6月1日买的空间和域名,到现在的2016年6月1日正好1年。这篇文章主要讲我这个草根站长这一年用来血的教训换来的SEO终极算法。血的教训1、学习了半个多月网络营销,弃学了…

全球银行网站成黑客主攻目标 阿里云提供安全防御应急方案

2019独角兽企业重金招聘Python工程师标准>>> 近日,阿里云监控发现,匿名者(Anonymous)组织成员正在发起针对全球中央银行网站的攻击行动,截止目前,国内有超过2家以上的重要网站被攻击&#xff0c…

SpringCloud GateWay 相关图形,文档、网站

一 业务:多个微服务的应用可能部署在不同机房,不同地区,不同域名下。 二 需求:统一入口、路由、权限认证...... 三 解决方案: 1 集群与架构(11) (1)逻辑 &#xff0…

Docker相关图形,网站、文档

一 引擎 引擎(Engine)是电子平台上开发程序或系统的核心组件。 一般而言,引擎是一个程序或一套系统的支持部分。 常见的程序引擎有游戏引擎、搜索引擎、杀毒引擎等。 游戏引擎:就是“用于控制所有游戏功能的主程序“。搜索引擎&a…

PHP搭建网站登录页面(一个iOS开发者的PHP之路)

前言 最近几年各个技术论坛流传着一句话:未来是全栈程序员的世界!程序员作为社会的一门职业,越来越多的人加入这个行业,在这个行业内分工很明晰的情况下,越来越多的程序员开始不安分追求一门编程语言,开始在…

网站分析参数(实例分析)SimilarWeb插件参数

网站分析参数(实例分析)SimilarWeb插件参数 那么这些指标是什么意思呢? SimilarWeb Rank:类似网站排名Global Rank:全球网站排名第三栏一般是类别,大概网站从事范围,比如进入知乎就是Internet a…

redis应用场景(1)一个文字投票网站

构建一个文章投票网站,一般具备下面几个功能发布文章文章投票评分(按投票多少进行评分)文章排序(按发布时间,按评分高低)文章分组(如专题)...1.关系型数据库设计其中用户&#xff0c…

Google Analytics SEO 实时 网站 访问量 统计

/**************************************************************************** Google Analytics SEO 实时 网站 访问量 统计* 说明:* 之前一直在想要怎么才能让aplexos.com域名网站能够统计访问量,网站是使用* github.io搭建&…

URLOS实战入门—制作LAP网站环境

1、制作LAP镜像 1.1.使用ssh登录宿主机器,创建Dockerfiel文件并填充以下内容 FROM php:7.2.16-apache-stretch ENV TIME_ZONE Asiz/Shanghai RUN sed -i s~//.*.debian.org~//mirrors.aliyun.com~ /etc/apt/sources.list \ && apt-get update \ && …

【网站优化实例教程】怎样运用分类信息网做网站优化【网优谷经验】

什么叫归类网络信息的营销推广?知道58个市和甘吉网知道什么叫分类信息网。 分类信息网现阶段其实早已被赶集网、58同城网那样的超大型网址垄断性,可是对于地区的分类信息网,還是有做头的。运用冷门行业的分类信息网开展提升,运用社…

分享12个非常好的免费矢量资源网站(转)

http://www.cnblogs.com/lhb25/archive/2011/04/08/2003802.html 在工作中,Web设计师经常需要到网上查找一些免费资源以更快更好的完成设计任务。这些资源都是到用时方恨少啊,所以今天本文与大家分享12个非常好的免费矢量资源网站,大家可收藏…

一个优秀的响应式网站能够给你带来什么?

网站作为你在互联网上的“门面”,这个脸一个要争!那该怎么样才能把自己在互联网的”脸面”整理的漂漂亮亮呢?打造一个优质的网站,不但让你“长脸”,还能让用户认得你,爱上你。提起优质的网站,说…

支付宝接口开发-手机网站支付-沙箱测试

前面一段时间,因为公司业务需求,需要使用支付宝的手机网站支付接口,因为自己也是第一次使用这个,中间走了不少弯路,现在总结一下,希望对遇到同样问题的朋友有帮助。 第一步:登录蚂蚁金服开放平台…

互联网安全和数据挖掘网站

检测、踩点网站:https://www.netcraft.com/ 转载于:https://www.cnblogs.com/ZQWelcomeIndex/p/11442145.html