SOA和RPC
随着互联网规模发展,面向服务的体系架构(SOA)成为主流的架构方式,SOA的本质思想是高内聚、低耦合地实现分治,各个系统之间通过服务的方式进行交互,这样保证了交互的标准性,这对于一个复杂的大规模系统来说显得尤为重要,子系统之间能够标准清晰地互相配合与沟通。同时,随着数据规模的飞速发展,从单一应用架构,再到拆分成多个子系统,演变成垂直应用架构,最后演变成分布式应用架构。此时,在一个分布式系统中,如何实现节点之间的RPC调用方式?如何实现服务的动态发现与路由?如何实现软件层面的负载均衡(4层还是7层更优)?这些都将成为我们要解决的问题。
体系化认识RPC
远程过程调用(Remote Process Call): 简单地来说,就是client通过网络来调用server的地址空间上的函数/方法,就跟调本地方法一样简单便捷,这样就相当于扩展了client的能力。一个RPC框架的实现必须考虑的几个核心组件如下:
RPC组成部分
- 传输协议:我们知道,七层网络协议栈中,从http到tcp,不过只是层层嵌套header而已,RPC传输的message可以只是TCP的body内容(也叫payload),也可以是header+body,那么基于TCP还是基于HTTP来实现RPC呢?它们各有优劣:
- 基于TCP可以更便于定制协议字段,减少网络传输字节数,降低网络开销,提高性能,增加并发数和吞吐量;这也带来实现代价高的问题
- 有利于跨平台的调用,因为json,xml这些传输标准是通用的,成熟的http框架也多,不比过于关心底层细节;不过由于是上层协议,传输需要占用的字节数多,导致传输效率低,往往通过使用Gzip压缩来优化
- 序列化和反序列化:也就是对象与二进制流(byte数组)之间的相互转化,如何高效稳定且能够跨平台地完成这个过程?也将成为设计中的考量,目前可选的有ProtoBuff,Hessian,bson等
- IO模型:选择一个合适的IO模型可以让server在更短时间内响应更多的请求,linux里的IO分为等待数据准备和把数据从内核拷贝到进程的两个阶段,严格意义上在《UNIX网络编程》中提到了5种,除了基于信号驱动的IO之外,还有以下几种:
- Blocking IO:IO调用无响应时,CPU就也挂起等待,也就导致线程或者进程被IO阻塞
- Non-blocking IO:通过设置socket使其变为non-blocking,当用户进程发出read操作时,如果kernel中的数据还没有准备好,那么它并不会block用户进程,而是立刻返回一个error。用户进程其实是需要不断的主动询问kernel数据好了没
- IO-multiplexing:基于内核的epoll或者kqueue实现,引入一个代理线程来监听所有的TCP连接(IO请求),有任何事件发生就通知用户态进行处理,避免用户态的CPU被IO阻塞;基本原理就是select/epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程。
- Async IO:理论上前3种都属于同步IO,异步IO是当进程发起IO请求之后,就直接返回,直到kernel IO操作完成之后发送一个信号告诉进程说IO完成,一般通过回调函数进行通知。
- 阻塞与非阻塞区别:调用blocking IO会一直block住对应的进程直到操作完成,而non-blocking IO在kernel还在准备数据的情况下会立刻返回,然后不断轮询,不过拷贝数据过程是阻塞的。
- 进程/线程模型:
- 协议结构:固定长度的header+playload
- 可靠性和易用性:网络闪断时如何保持心跳?
基于TCP的RPC
最简单的方式,例如基于Java Socket API实现RPC,一种非常典型的CS架构,client携带参数和调用方法名请求server,server使用一个while循环来监听客户端请求并予以处理;再往下延伸就涉及到当client请求并发数很大时,是用阻塞IO还是非阻塞IO?如何做服务路由以及负载均衡来将请求分发到多个server?轮询法?
基于HTTP的RPC
基于HTTP一定程度上就是为了节省在底层细节上的关注,而可以去利用更高层的协议和现有的开源库去实现RPC,例如基于HttpClient库去实现RPC,基于json或者xml作为序列化之后的传输格式,当然这也会带来效率低,定制化程度低等弊端。
RESTFul和RPC形式url
RESTFul把所有网络上的实体作为资源,具体的资源通过不同的格式作为表现层,例如图片的表现层可能是jpg,也可能是png;然后通过http协议的常用操作方式(例如GET、POST等)来改变和转换资源状态,也就是表现层转换
而传统的RPC形式url会把操作类型、需要远程调用的服务接口名、参数都通过queryString携带到服务端,RESTFul则把操作类型放到了http请求方式中,使得url更加简洁,只留下一部分参数在url中
RPC相关
- RPC和HTTP之间区别:HTTP 调用其实也可以看成是一种特殊的 RPC,只不过传统意义上的 RPC 是指长连接数据交互,而 HTTP(1.x) 一般是指即用即走的短链接; 当 HTTP 协议进化到 2.0 之后,Google 开源了一个建立在 HTTP2.0 协议之上的通信框架直接取名为 gRPC,也就是 Google RPC,这时 HTTP 和 RPC 之间已经没有非常明显的界限了
服务路由和负载均衡
所谓SOA,也就是把共用组件和共用逻辑提取成为可以复用的服务,这样一来,一个大型系统中的服务就会越来越多,如何通过服务路由来找到需要的服务以及通过负载均衡算法来均匀地将请求分配到一个服务集群下面对应的某台机器,就显得尤为重要。现在陆续使用zookeeper来做服务配置中心,取代原来的硬件负载均衡F5或者LVS/Nginx软件方案,避免单点故障,动态注册和下线服务。
常用负载均衡算法
- 轮询法与加权轮询
- 随机法与加权随机
- 源地址Hash法:对来源IP % Server数目,将同源IP请求分发到了同一台Server,有利于保持CS之间的Session会话,但是如果存在缓存,服务器上下线带来的雪崩需要考虑引进一致性哈希算法
- 服务端最小连接数法
- 动态策略配置:服务端Groovy脚本动态加载或者Zookeeper Watch机制
Zookeeper
类似于一个精简版的文件系统,一种分布式集群中的协调系统,包括配置维护,名字服务,一致性与同步状态,动态服务注册,服务发现等;内部使用Zab协议提供一致性,leader与follower之间同步状态;基于Watcher机制,zookeeper维护的节点状态发生变化时,client会收到通知。
Http服务网关
由于Http协议明文带来的不安全性,再加上随着互联网发展,多个client端需要复用同一套后端服务,需要考虑引入Http网关来作为安全权限校验模块,请求先到达网关,网关再去查询服务配置中心,找到对应的服务并调用,取出需要的数据返回给多个client;这样一来,服务就被隐藏,不再对外直接提供服务,网关就成为所有服务的所依赖的核心节点,流量相当于所有服务节点之和,那么网关集群的可扩展性和监控系统就显得尤为重要,一般我们可以选择网关与服务机器一对一的架构方式。
分布式系统基础设施
一个大型、稳健、成熟的分布式系统,包括许多部分。
分布式缓存
- redis或者memcache,分布式对象缓存系统
- 一致性哈希引入虚拟节点,解决缓存雪崩和不均衡问题
- 分布式session应用:在分布式系统中要保存session会话,传统做法会考虑用cookie来做同步,存在安全性和数据大小有限的问题;也可以考虑持久化到DB中,显然这会极大地影响到系统吞吐量;此时,我们考虑引入分布是缓存作为同步session的集群,它既可以放在web server集群之后,也可以放在之前,也就是sticky和non-sticky两种模式,达到多台server之间session共享与同步的效果,还能增加系统的容错性。
去IOE的持久化存储
MySQL拓展:传统关系型数据库在查询方式上非常完善,支持group,join,order等复杂方式,但是并不支持高并发访问和海量数据存储,为了应对规模扩展,在扩容上要做以下考虑与规划
- 业务拆分:比如将表迁移到库
- 复制策略:常见的Dual-master架构,单个master可写,多个slave和stand by master只可读(提高并发读能力),实现读写分离以及避免master单点故障,减少停机维护时间,也就是减少不可写时间
- 分表:水平切表,例如uid%256这种方式,将一张大表切成256张表,每张表记录数下降,可以提高查询效率
- 分库:然而以上方式都没法解决数据库并发写效率低的问题,此时就需要分库,同样采用Hash方式把数据拆分到多个库中
- 分库分表:带来查询性能和并发访问能力的提高,却要求必须指定路由字段进行查询,而且对于关联查询,分布式事务的支持都将成为新的问题
HBase:并发写入能力出色,因为具有多个region server;可用于处理海量数据存储,可扩展性和伸缩能力强;放弃关联查询,一致性,事务等复杂特性,可以通过ES等搜索引擎来实现组合查询
- 构建在HDFS之上的一种列式存储数据库,数据以表的形式组织,每个表由行列组成,行列确定存储单元,每一列属于一个列族,并支持时间戳来标识多版本;表支持自动分裂成多个region
Redis:更好的读写吞吐能力,支持高并发,以及丰富的数据类型,可以提高高性能缓存服务
分布式消息队列
主要用于系统之间的通信与解耦,异步通信机制可以提高系统的吞吐能力,而且在高峰期可以作为系统的缓冲存在。包括Kafka,ActiveMQ等。
ActiveMQ(JMS):JMS两种消息发送接收模型,一种是点对点之间的P2P模型,另一种是一对多广播时的发布订阅模型
业务规模与并发请求数的提高,一方面需要我们进行垂直扩展,例如提升机器性能,优化内存配置,阻塞IO变NIO等。水平扩展方法包括水平拆分topic到多个broker中等方式。
垂直化搜索引擎
- Lucene:
- 倒排索引:建立词和文档之间的映射关系
- 分词:中文分词包括CJKAnalyzer、MM分词、庖丁分词
- 相关性排序:
- 关键概念:
- ElasticSearch:Elasticsearch是一个建立在全文搜索引擎 Apache Lucene™ 基础上的搜索引擎,可以说Lucene是当今最先进,最高效的全功能开源搜索引擎框架。Elasticsearch使用Lucene作为内部引擎,还提供以下功能:
- 分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索。
- 实时分析的分布式搜索引擎。
- 可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据。
互联网安全架构
常见Web攻击手段和防御方法
XSS跨站脚本攻击
没有对用户在表单输入的html代码做转义,把代码当做了数据保存,那么在页面重定向或者加载数据时就出现执行脚本的情况,从而盗取用户cookie,密码。
可以通过urlEncode予以特殊字符串的处理来防止该攻击
CRSF跨站请求伪造攻击
攻击者盗用受信任用户的账号,伪装成受信任的请求访问网站,一般通过利用浏览器cookie实现。
解决方法:把cookie设置成httpOnly,避免被脚本读取cookie;服务端生成定时过期的Token,每次请求都需要携带token,会话过期时token失效;设置请求的referer字段,标明该http请求的来源地址
SQL注入攻击
把SQL命令伪装成请求参数传入到Server端,从而对数据库内容进行修改或者删库操作;例如传一个参数为’or ‘1’=’1,这样可以空密码登录。
解决方法:使用预编译语句或者ORM框架,预先对特殊字符进行转义;哈希加盐法来避免密码明文存放,DB中保存Hash值和Salt值,每次对Key+Salt做指定摘要处理之后再合Server保存的值比对,避免彩虹表和穷举攻击;处理好异常信息和重定向页面,不暴露数据库等版本信息。
文件上传漏洞
攻击者利用服务器不检测文件类型的漏洞,上传脚本或者木马文件进行攻击,或者上传大型文件把server当做免费存储使用,
解决方法:对文件类型进行白名单校验,通过比较文件开头几个字节内容(魔数)来判断;文件重命名防止找到文件路径;文件大小限制
DDos分布式拒绝服务攻击
- SYN Flood:TCP作为一个面向连接的协议,三次握手环节中的第二步,通过伪造IP发送大量的SYN报文给服务端,服务端处于SYN_RECV状态,不断重试轮询、分配资源,导致正常请求不能得到处理。
- DNS Query Flood(UDP Flood):向服务器发送大量的域名解析请求,随机生成域名,导致服务器不能读取缓存,而是层层往上读取,最终导致域名解析超时
- CC攻击(Http Flood):利用肉鸡或者http代理向服务器发送海量http请求,避开缓存或者需要大量的DB请求,从而拖垮业务处理系统,甚至DB
- DNS域名劫持,CDN回源攻击,服务器权限提升,缓冲区溢出等其他攻击
常用安全算法
数字摘要
- MD5:为输入生成一个128位的摘要,作为数字指纹,利用它来验证消息的完整性;相似消息的摘要差异巨大,可逆性很小
- SHA256:Secure Hash Algorithm,生成256位摘要
- HMAC: 利用MD5或SHA1等哈希算法, 增加一个随机数来生成摘要,避免被彩虹表反解
对摘要信息编码:因为摘要中可能存在无法显示的特殊字符串,需要编码(base编码原理)[https://blog.csdn.net/wangjianno2/article/details/52464208]
- 十六进制编码:把二进制数组转化成十六进制来表示, 也叫Base16编码,一共16个字符0-F表示byte数组内容,一个字节8bit需要2个十六进制字符(一个字符占用1byte)来表示,空间扩大一倍
- Base32: 类似Base64,用32个可见字符表示二进制数组(ASCII字符),一个字节转化成Base32之后会在前边补3个0,因为32是2的5次方
- Base64:用64个可打印字符来表示二进制数据,64个字符分别是A-Z、a-z、0-9,还有2个因为系统不同而不一样;3个字节24位数据需要4个字节来表示; 其中汉字本身可以有多种编码,比如gb2312、utf-8、gbk等等,每一种编码的Base64对应值都不一样
- ASCII,Unicode 和 UTF-8
对称加密
加解密使用同一个密钥,计算量较小,速度较快,存在密码泄露风险。
- DES、3DES:64位密钥长度,从56位参与DES运算到扩大成3*56
- AES:最低128位密钥长度。可以指定IV(Initial Vector),不同的系统只要IV不同,用相同的密钥加密相同的数据得到的加密结果也是不同的
非对称加密
使用私钥加密,然后对方用公钥解密,避免私钥在传输过程中泄露,往往用于保证数据完整性;或者先生成一对公钥私钥,然后广播公钥,对方用公钥加密之后发给自己,然后自己用私钥解密。
由于非对称加密速度慢,两种方式结合来达到更好的效果:先用对称加密对大文件进行加密,然后再对文件密钥使用非对称加密,也就是用公钥加密,然后发送给对方,对方再使用私钥解密,这样就防止了密钥泄露。
- RSA:基于数论事实,将两个大素数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥
数字签名(MD5withRSA or SHA256withRSA)
发送方将原文的MD5等摘要信息,用私钥进行加密得到密文,然后将原文和密文一起发送给对方,对方用公钥解密密文,得到摘要,判断其和原文的摘要(使用同样的摘要计算方法)是否一致;其中对摘要加密得到的就是数字签名,可以用于确保传输数据的完整性,防止被第三方篡改
数字证书
类似于身份证书,用于标识网络中的身份;数字证书会携带公钥信息,数字签名等内容,一般由CA负责签发(也就是进行数字签名),使用keytool、OpenSSL进行证书管理
摘要认证
为了防止通信过程中数据被篡改或者客户端伪造请求,因此利用摘要认证来对客户端身份,以及客户端请求参数等内容进行认证;之所以不采用https是因为性能成本以及需要额外申请CA证书;摘要认证本质上采用了对称加密手段,实现方式为:client和server采用同样的秘钥和摘要算法,将参数排序之后生成摘要,然后每次交互都带上内容和利用秘钥生成的摘要,每次对方都会进行摘要校验,确保内容未被篡改。
签名认证
摘要认证存在secret泄露的安全问题,因为client和server使用同样的密钥;因此我们引入签名认证,也就是利用数字签名做认证,采用非对称加密手段,client采用密钥加密,然后server采用公钥解密,防止私钥泄露问题
HTTPS协议(基于SSL的http协议)
尽管摘要认证和签名认证可以解决client和server之间身份认证问题和内容防篡改问题,但是由于http明文传输,如果进行抓包或者中途拦截,内容很容易被监听和暴露,因此我们需要https。
https作为一种数字证书,包含公钥,数字签名,拥有者信息等内容。本质上就是在http和TCP之间加了一层安全层,采用SSL(安全套接层)或者TLS,来将内容加密。https支持单向认证和双向认证两种方式。一般像银行网银,支付宝这种都是双向认证。
SSL/TLS本身又包括两层,记录协议和握手协议,分别负责不同的工作。握手过程生成对称加密的密钥,并交换密钥。
http和https区别
- https = http + tls协议(从SSL演变到TLS, 都是一种传输层加密协议,位于应用层和传输层之间) + 传输加密 + 身份认证 —-> 保证传输过程中的安全性,因为http传输的是明文内容,也不对传输双方进行身份验证
2.https保证以下三点:- 内容加密。浏览器到百度服务器的内容都是以加密形式传输,中间者无法直接查看原始内容。非对称密钥交换算法。建议优先使用 ECDHE,禁用 DHE,次优先选择 RSA;证书签名算法默认都是使用 RSA 签名;对称加解密算法。优先使用 AES-GCM 算法,针对 1.0 以上协议禁用 RC4;
- 身份认证。保证用户访问的是百度服务,即使被 DNS 劫持到了第三方站点,也会提醒用户没有访问百度服务,有可能被劫持。主要涉及到 PKI(公钥基础设施)和数字证书
- 数据完整性。防止内容被第三方冒充或者篡改。openssl 现在使用的完整性校验算法有两种:MD5或者SHA,由于 MD5 在实际应用中存在冲突的可能性比较大,尽量别用MD5来验证内容一致性。SHA 也不能使用 SHA0 和 SHA1,已被破解,建议使用 sha2 以上的安全哈希函数。
- 中间劫持:用户数据在浏览器和百度服务器中间传输必须要经过的节点。比如WIFI热点,路由器,防火墙,反向代理,缓存服务器等,都可能出现劫持。例如,运营商的内容劫持是如何进行的,运营商会分析你的网络请求,它可以先于网站回包,也能修改数据包的内容。所以它可以让你跳转一次,在网址上加上小尾巴,也能在你访问的页面弹出小广告
图解https
Go和https
https对性能的影响
- HTTPS会降低用户访问速度(协议交互所增加的网络RTT(round trip time+加解密相关的计算耗时30ms),增加网站服务器的计算资源消耗;非对称密钥交换很安全,但同时也是HTTPS性能和速度严重降低的“罪魁祸首”。
优化策略
HTTPS 访问速度优化
- Tcp fast open:HTTPS和HTTP使用TCP协议进行传输,也就意味着必须通过三次握手建立TCP连接,但一个RTT的时间内只传输一个 syn 包是不是太浪费?能不能在syn包发出的同时捎上应用层的数据?其实是可以的,这也是tcpfastopen的思路,简称TFO。遗憾的是 TFO需要高版本内核的支持,linux从3.7以后支持TFO,但是目前的windows系统还不支持TFO,所以只能在公司内部服务器之间发挥作用。
- Session resume:顾名思义就是复用session,实现简化握手
- Session cache 的原理是使用 client hello 中的session id 查询服务端的sessioncache,如果服务端有对应的缓存,则直接使用已有的session信息提前完成握手,称为简化握手
- Session ticket的原理参考RFC4507。简述如下:server将session信息加密成ticket发送给浏览器,浏览器后续握手请求时会发送 ticket,server 端如果能成功解密和处理 ticket,就能完成简化握手。显然,session ticket 的优点是不需要服务端消耗大量资源来存储 session 内容。
- HSTS(HTTP Strict Transport Security)。服务端返回一个HSTS的http header,浏览器获取到HSTS头部之后,在一段时间内,不管用户输入www.baidu.com还是http://www.baidu.com,都会默认将请求内部跳转成https://www.baidu.com。
- Ocsp stapling
- False start:原理就是在 client_key_exchange 发出时将应用层数据一起发出来,能够节省一个 RTT
- 使用 SPDY 或者 HTTP2: SPDY 最大的特性就是多路复用,能将多个 HTTP 请求在同一个连接上一起发出去,不像目前的 HTTP 协议一样,只能串行地逐个发送请求。Pipeline 虽然支持多个请求一起发送,但是接收时依然得按照顺序接收,本质上无法解决并发的问题。
HTTPS 计算性能优化
- 优先使用ECC椭圆加密算术相比普通的离散对数计算速度性能要强很多;对于 RSA 算法来讲,目前至少使用 2048 位以上的密钥长度才能保证安全性。ECC 只需要使用 224 位长度的密钥就能实现 RSA2048 位长度的安全强度。在进行相同的模指数运算时速度显然要快很多。
- 使用最新版的 openssl
- TLS 硬件加速方案主要有两种:SSL 专用加速卡+ GPU SSL 加速。
- TLS 远程代理计算
OAuth第三方授权—-开放资源授权的标准协议
旨在为用户资源的授权访问提供一个安全开放的标准,核心场景就是第三方登录。平台通过OAuth协议,提示用户对第三方授权使用部分用户数据,不需要触及用户名密码,就能给出授权。核心思想都是对用户资源做权限分级和隔离,ISV引导用户在平台端登录,完成授权,然后ISV就可以用用户的私有数据,且授权可取消。具体授权过程
系统稳定性
一个系统要保持稳定,上线之前就需要有充分的压力测试,并做好容量预估,准备好应急预案,并且具备一定的日志分析和错误定位能力,以便于遇到线上各种问题时快速定位解决。
在线日志分析
常用shell命令
集群监控
监控指标
- load:特定时间间隔内CPU运行队列中的线程数,一般正常为3以内,到达5以上认为负载过高。可以使用top和uptime来查看average load。
- CPU利用率:各种时间占CPU总时间的比例。通过
top|grep cpu
查看各种状态占比,1查看不同核的CPU状态,top -p pid
查看指定进程的CPU利用率,shift+H
查看线程的cpu利用率。 - 磁盘剩余空间:
df -h
,du -sh
- 网络traffic:
sar -n DEV 1 1
抽样查看各个网卡的网络流量 - 磁盘IO:IO密集型应用的瓶颈(例如数据库和文件系统),
iostat -d -k
查看磁盘IO状况。 - 内存使用:
free -m
,vmstat
- QPS:每秒query数。根据压测和运维经验评估得到,代表了系统的业务繁忙程度。
- RT:请求响应时间。可以用缓存、CDN节点、内容压缩等方法来降低RT
- 数据库相关参数:select/ps、update/ps、delete/ps来衡量不同类型的数据库操作指标,因为数据库读写耗费资源不同。
- JVM GC:Java stop the world引起的工作线程暂停响应问题,包括发生在老生带的缓慢major GC和新生代的快而频繁的Minor GC
心跳检测: 分布式系统中机器规模大,从而导致故障概率增大,所以需要集群心跳检测机制来实时处理slave、master宕机等各种状况。当然也包括业务系统的心跳检测。
- ping:使用的ICMP协议,检查网络链路是否畅通
- 应用层检测:预留自检页面,监控系统用脚本执行
curl
命令看返回结果是不是可以访问;或者curl -I
检查不同页面的返回header是否正常
- 容量评估:总体PV分散到多个具体页面,评估需要的机器数量,带宽,然后用CDN缓存,网页静态化等措施降低访问延迟。根据八二原则,
峰值QPS=(总PV*80%) / (60*60*24*20%)
,需要的机器数等于峰值QPS除以单台机器极限QPS,而单台机器极限QPS需要根据RT要求和机器是否出现瓶颈来确定,一般是一个曲线;系统水位图作为实时监控指标。
流量控制
限制系统QPS,限制系统总并发请求数,引入白名单机制,引入分布式消息队列来将用户请求异步化,削峰填谷,这些都是流量控制的具体措施。
分布式系统的复杂导致互相依赖,引入依赖管理来分析依赖关系和各个部分的压力,采取降级措施来避免故障传递。区分服务的优先级,引入白名单和开关,必要时舍弃非核心服务。不同情况有不同的处理方案。
高并发系统设计
- 原子操作:数据库事务,CAS操作,原子变量
- 多线程同步:synchronized和锁、可重入锁
- 数据一致性:CAP理论导致的三种程度的一致性
- 系统可扩展性:很方便地增加机器来水平扩展集群,来使得系统处理能力线性增长。
- 并发减库存案例:活动时瞬时QPS爆炸式增长,由于分布式缓存,数据库分库技术的引进,导致缓存和数据库之间难以实现事务,很容易出现缓存和数据库数据不一致导致的超卖和少卖现象,那么如何解决呢?将实际库存和浏览库存分离,一个在DB,一个在Cache,及时同步就行。DB采用innodb引擎,线程并发更新DB只需要行锁,进一步优化将行拆分,请求过来通过hash方式分发到不同的子行。
性能优化—-更少资源更快地服务更多用户
- 前端优化:YSlow分析网页性能,Firebug查看页面加载时间和请求响应时间,Java Btrace工具追踪耗时方法。
- 优化页面http请求数量,包括合并样式和脚本文件
- 变化较少文件存储到CDN
- 启用Gzip压缩
- 代码优化:单例模式减少系统开销,多线程和线程池,同步改异步,减少上下文切换,降低锁竞争
- 压缩与缓存:
- GC日志分析:
- 减少Full GC,-Xms等参数的配置,jmap定位代码错误
数据库查询:MySQL慢SQL日志功能—-log_slow_queries。
- 数据库索引优化,避免全表扫描
- 反范式设计,允许数据冗余,避免关联查询和全表扫描
- 使用查询缓存
- 换用搜索引擎来解决跨表查询和分组操作,引入KV存储来支持高并发读写
系统资源状况:
- 硬件性能提升,SSD盘,高内存,高吞吐网卡,多核和超线程技术
性能测试工具:①ApacheBench可以模拟并发请求来测试服务器在高负载情况下支持的QPS和RT。②Apache JMeter不止于http测试。③反向代理引流来调节权重,灰度发布测试性能。④TCPCopy工具可以将线上真实请求复制到测试机器。
- Java应用故障排查工具:
- jps查看JVM进程信息,例如进程主类对应的PID
- jstat监控虚拟机运行状态,包括类加载、内存使用、垃圾回收等方面
- jinfo查看程序的配置参数,查看和修改JVM运行时参数
- jstack查看当前JVM所有线程的堆栈信息
- jmap查看等待回收对象队列以及堆的概要信息、转储快照
- BTrace用于在不改代码,不重启应用情况下动态查看程序运行细节
- Jconsole连接本地或远程JVM,监视应用的性能和资源消耗情况
- MAT分析Java对信息,Eclipse插件
- VisualVM,啥也能干的JDK工具
- 案例分析:①内存OOM,利用VisualVM dump堆信息。②线程死锁或者信号量没释放,表现症状为CPU load低,但是请求响应超时,可以线程dump分析 ③类加载冲突
大数据分析
分布式系统的日志收集(ELK等)
几种常用的日志收集方式:
- 文件轮询机制定时读取整个日志文件
- inotify机制读取日志修改事件,通过CMS写入消息队列,然后各种服务订阅收集,用作分析用途
日志分发机制—-分布式消息队列,既可以解耦,也可以起到削峰填谷的缓冲效果
日志收集分析架构:inotify—>消息队列—>流式处理系统—>存储—>分析展现系统。参考框架Chukwa
离线数据分析
对时间要求不高,分析完之后可以数据回流到DB提供实时在线查询服务。Hadoop的主要场景就是离线批处理数据。
流式数据分析
storm是一种分布式实时计算系统,主要用来实时处理流式数据
数据同步与报表
- 每天在OLTP系统负载最低时定时全量或者增量将数据从OLTP同步到OLAP系统,用于离线分析。
- 离线数据同步:sqoop开源数据同步工具,利用MR来完成DB和HDFS之间的数据同步和转换,效率很高。
实时数据同步:
- 利用消息系统进行实时增量数据同步,其他系统订阅topic就行
- 类似mysql主从同步,通过binary log重放,变更同步
数据报表:Highcharts
大数据生态系统
- Hadoop = HDFS + YARN + MapReduce
- HDFS负责大数据存储,高可靠、高容错、高扩展、低成本、高吞吐的分布式文件系统
- YARN负责资源调度,依然发挥重要作用
- MapReduce并行编程模型和计算框架
- Hbase主要解决实时海量数据查询问题
- Hive和Pig主要解决数据处理和计算问题,分别以SQL形式和脚本形式,例如通过HiveSQL写SQL查询语句,会转化成MR操作,不实时,主要用于离线分析。
- 如何用形象的比喻描述大数据的技术生态?Hadoop、Hive、Spark 之间是什么关系?