今天继续坑系列,高可用
已经讲过了,当前互联网时代,怎么少的了高并发
呢?高并发
和高可用
同样, 已经变成各个系统的标配了,若是你的系统QPS没有个大几千上万,都很差意思跟人打招呼,虽然可能天天的调用量不超过100。前端
高并发
这个词,我我的感受是从电商领域开始往外流传的,特别是电商领域双11那种藐视全球的流量,再把技术架构出来分享一把,如今搞得全互联网都在说高并发
,并且你注意回忆一下全部你看到的高并发系统,每每都逃不开一个核心概念,那就是缓存+哈希
,一切都是以这个概念和基础的,仿佛这就是高并发的核心技术了。`面试
围绕这个核心技术,一般咱们看到的各类高并发的架构系统,在博客,论坛,现场分享出来的高并发系统,都跑不出如下几个方面的东西。redis
就是那种单个页面流量巨大无比,每秒的QPS几十万上百万的系统,确实并发高的系统
,核心解决方案就是静态化,靠机器和带宽去抗,假如没有CDN的话,全部流量都落到同一个IP下面的话,基本上也就是用Nginx的文件静态化了,单机的承受能力主要取决于带宽和单机的性能,要再多的话,那就LVS(或者F5)+集群
了,这种的典型场景就是搞活动时候的首页,活动页面了,还有就是引流搜索引擎的着陆页了,通常都是现成的图片和文字静态化,固然,这种还有不少前端的技巧和技术了,这一点我不是很了解,就不得瑟了,就中后台来讲,大部分状况下直接Nginx搞定了,核心仍是使用了缓存技术
。算法
读写分离是你们看到的第二个高并发的架构了,也很常规,由于通常状况下读比写要多得多,因此数据库的主库写,从库们提供读操做,一下就把数据库的并发性能提升了。数据库
若是还不够,那么分库分表把,把数据分到各个数据库的各个机器上,进一步的减小单台机器的压力,从而达到高并发
的目的。编程
若是是分库分表,有时候使用的就是哈希技术
了,以某个字段哈希一下而后来分库分表,读写分离的读操做,基本也是经过哈希技术
把读落到不一样的机器上去减轻单机压力。后端
说到高并发,不得不说缓存了,如今各类缓存的工具也不少也很成熟,memcache
,redis
之类的KV数据库做为缓存已经很是成熟了,并且基本上均可以集群化部署,操做起来也很简单,简直变成了一个高并发
的代言词了,核心就是缓存技术
了,而memcache
和redis
只是用来实现这个缓存技术的工具而已。缓存
但凡大数据处理,高并发系统,必言哈希,随机插入,时间复杂度O(1),随便查询,时间复杂度O(1),除了耗费点空间之外,几乎没什么缺点了,在如今这个内存廉价的时代,哈希表变成了一个高并发系统的标配。性能优化
咱们来看个例子,看看一些个你们眼中标准的高并发系统的设计,这些设计你们应该都看过,无非就是上面的几个要点,最重要的就是缓存+哈希
,这两个东西的组合好像无所不能。微信
活动秒杀页面,这是个标准的高并发吧,到了搞活动的那个时刻,单页面的访问量是天量数据了,但这种系统有个特色逻辑简单,只要带宽和性可以,就必定能提供稳定的服务
服务能迅速的返回数据便可,没有什么计算逻辑,这种高并发系统的设计基本上就是在怎么压榨机器的IO性能了,若是有CDN绝对使用CDN,能在本机读取的毫不走网络获取,能读取到内存中毫不放在硬盘上,把系统的磁盘IO和网络IO都尽量的压榨,使用缓存+哈希
技术,只要设计合理,99%的状况能搞定。
活动页面的冲击感实在太强,想象一下几千万人同时访问网站尚未挂,让不少人以为高并发
应该就是这样子,这估计也是高并发
此次常常在电商技术中出现的缘由吧,由于搞个活动就能够搞出一个高并发
事件。
这样的场景再扩展一点,就是凡是能提早提供数据的并发访问,就能够用
缓存+哈希
来搞定并发。
接下来,咱们再看看这个星球并发量最疯狂的网站,瞬间的访问量碾压其余网站的12306,这种场景下的高并发也有个特色,那就是虽然量大,但其实没法给每一个用户提供服务
。
相似的其实还有商品的抢购系统,商品和车票一共就1000张,你100万的人抢,你系统作得再好,也没法给100万人提供服务,以前12306刚刚上线的时候不少人喷,说若是让某某公司来作确定能作好,但你们不少只看到了表面,让某很厉害的公司来作,最多也只能作到你们访问的时候不会挂掉,你买不到车票仍是买不到,并且如今的12306体验也已经作得很好了,也不卡了,可是仍是不少人骂,为何?还不是由于买不到票。
对于这样的系统,设计关注的就不只仅是提升性能了,由于性能瓶颈已经摆在那了,就1000张票,作得更多的是分流和限流了,除了缓存+哈希
来保证用户体验之外,出现了奇葩验证码,各个站点分时间点放票。而后经过排队系统来以一种异步
的方式提供最终的服务。
咱们给这样的场景再扩展一下,凡是不能提早提供数据的,能够经过
缓存+哈希
来提升用户体验,而后经过异步方式
来提供服务。
若是把上面两个场景的状况合并一下,仿佛缓存+哈希
变成万能的了,不少人眼中的高并发
就是上面的场景的组合,认为缓存+哈希
就能够解决高并发的问题,其余的场景中,加上缓存
提升读写速度,在加上哈希
提供分流技术,再经过一个异步
提供最终服务,高并发就这么搞定了,但其实是不是这样呢?显然没那么简单,那如何来设计一个高并发的系统呢?
举个例子来讲吧,搜索提示功能你们都知道吧,就是下面这个图的东西。
若是是google,baidu这种大型搜索系统,或者京东淘宝这种电商系统,搜索提示的调用量是搜索服务自己调用量的几倍,由于你每输入一个键盘,就要调用一次搜索提示服务,这算得上是个标准的高并发
系统吧?那么它是怎么实现的呢?
可能不少人脑子里马上出现了缓存+哈希
的系统,把搜索的搜索提示词存在redis
集群中,每次来了请求直接redis
集群中查找key,而后返回相应的value值就好了,完美解决,虽然耗费点内存,可是空间换时间嘛,也能接受,这么作行不行?恩,我以为是能够的,但有人这么作吗?没有。
了解的人应该知道,没有人会这么来实现,这种搜索提示的功能通常用trie树
来作,耗费的内存很少,查找速度为O(k),其中k为字符串的长度,虽然看上去没有哈希表的O(1)好,可是少了网络开销,节约了不少内存,而且实际查找时间还要不比缓存+哈希
慢多少,一种合适当前场景的核心数据结构才是高并发
系统的关键,缓存+哈希
若是也当作一种数据结构,但这种数据结构并不适用于全部的高并发
场景,因此
高并发系统的设计,关键在合理的数据结构的设计,而不在架构的套用
有了上面的数据结构,而且设计出了系统了,拿到线上一跑,效果还行,但感受没达到极限,这时候可千万不能就直接上外部工具(好比缓存)提高性能,须要作的是不断的代码性能的优化,简单的说,就是不断的review你的代码,不断的找出能够优化的性能点,而后进行优化,由于以前设计的时候就已经经过理论大概能算出来这个系统的并发量了,好比上面那个搜索提示,若是咱们假定平均每一个搜索词6个字符,检索一次大约须要查询6次,须要2-3毫秒,这样的话,若是8核的机器,多线程编程方式,一秒钟最多能接受3200次请求(1000ms/2.5ms*8),若是没达到这个量级,那么确定是代码哪里有问题。
这个阶段可能须要借助一些个工具了,JAVA有JAVA的性能优化工具,你们都有本身以为好使的,我自己JAVA用得不多,也没啥可推荐的,若是是Golang的话,自带的go tool pprof
就能很好的进行性能优化。
或者最简单的,就是把各个模块的时间打印出来,压测一遍,看看哪一个模块耗时,而后再去仔细review那个模块的代码,进行算法和数据结构的优化,我我的比较推崇这个办法,虽然比较笨,可是比较实在,性能差就是差,比较直观能看出来,也能看出须要优化的点,并且比较贴近代码,少了外部工具的干扰,可能也比较装逼吧。
这个过程是一个长期的过程,也是《重构:改善代码的既有设计》中提到的,一个优秀的系统须要不断的进行代码级别的优化和重构,因此
高并发系统的实现,就是不断的优化你代码的性能,不断逼近你设计时的理论值
以上两个都完成了,并发量也基本达到理论值了,可是还有提高的需求,这时候再来考虑外部的通用方法,好比加一个LRU缓存,把热词的查询时间变成O(1),进一步提升性能。
提及LRU,多说一句,这是个标准的缓存技术
了,实现起来代码也不复杂,就是个哈希表+链表
的数据结构,一个合格的开发人员,即使没有据说过,给定一个场景,应该也能本身设计出来,我见过不少简历都说本身有大型高并发系统的开发经验,能熟练运用各类缓存技术,也对缓存技术有深刻的了解,可是一面试的时候我让他写个LRU,首先有50%的人没据说过,OK,没听过不要紧,我描述一下,而后给一个场景,硬盘上有N条数据,而且有一个程序包,提供GET和SET方法,能够操做磁盘读写数据,可是速度太慢,请设计一个内存中的数据结构,也提供GET和SET方法,保存最近访问的前100条数据
,这个数据结构就是一个LRU了,让面试者实现出来,若是以为写代码麻烦,能够把数据结构设计出来描述一下就好了,就这样,还不少人不会,这怎么能说是对缓存技术有深刻了解呢?就这样,怎么能说有过大型高并发系统的经验呢?这只是开源工具的使用经验罢了。
在没把系统的性能压榨彻底以前,不要使用外部的通用方法,由于使用了之后就没有太多进一步优化空间了。
上面几种都已经弄完了,还须要提高性能,这时候再考虑运维的技术了,好比常规的加负载均衡,部署成集群之类的,经过运维和部署的方法提升服务的并发性。
高并发
系统只是相对的,没有什么无上限的高并发,流量的洪流来了,再高的高并发同样挂,新浪微博的高并发
应该作得很好吧?可是林心如
发条微博说她和霍建华
谈恋爱了,同样把微博搞挂了(非官方消息啊,我猜想的,呵呵,那天下午新浪微博正好挂了),呵呵,你说要是TFBOY
明天过生日,微博是否是要连夜加几个redis
集群啊?若是有微博的朋友,留个言溜溜呗:)
罗里吧嗦说了这么多,其实我就想表达一个意思,无论是前面的高可用
,仍是今天的高并发
。
代码才是关键,架构都是锦上添花的东西,既然是锦上添花的,必然坑多,没有什么捷径。
代码的健壮性决定了高可用,这些印度人就能作到,而高性能,高并发须要的不只仅是代码的健壮性,还有数据结构的设计和代码的调优能力了。
架构模式是你们总结出来的,和你的系统可能关系不是很大,学习太多的架构,脑壳会乱,还不如实打实的看几本书,而后对着架构多推敲练习,不少人对数据结构嗤之以鼻,以为对于现有的开发来讲,数据结构没那么重要了,但对于后端开发来讲,数据结构是很重要的技能,虽然面试的时候不会让你去翻转一棵二叉树,但二叉树是什么,什么场景下用仍是应该知道的吧?
找准合适的数据结构,不断的优化代码,这样来提高你的系统性能,这样的系统才是你可控的,才有不断优化的空间,更好的高并发
,若是一开始就上外部的缓存技术
,极可能若是性能达不到要求,就没有优化空间了,由于要修改外部的系统仍是很困难的。
这几篇我以为我都在瞎扯淡,虽然比较虚,但也是我工做这么些年淌坑无数之后的总结吧,后面的文章会写一些实际的了,个人搜索引擎部分还没写完呢。尽请期待。呵呵。。
若是你以为不错,欢迎转发给更多人看到,也欢迎关注个人公众号,主要聊聊搜索,推荐,广告技术,还有瞎扯。。文章会在这里首先发出来:)扫描或者搜索微信号XJJ267或者搜索西加加语言就行