一、认识服务的规模linux
注册用户,独立用户web
请求数正则表达式
繁忙时流量算法
服务器台数sql
貌似应该有不少其余的指标,之前都据说过,可是历来没有认真分析过,已经上线的系统也没有对此进行过统计和分析!数据库
二、大规模服务中的问题有如下几点:编程
可扩展性、负载均衡的必要性缓存
通常来讲,当一台服务器没法承担负载时,都会采用横向扩展(scale out)或者纵向扩展(scale up)。横向扩展就是经过服务器的数量来分担负载,纵向扩展是经过提升硬件的性能来处理负载。而咱们知道,硬件的性能和价格不是成比例的,因此一般采用横向扩展技术!采用横向扩展也会带来问题,如请求如何分配——负载均衡,数据如何同步,网络通讯延迟等。服务器
保证冗余性网络
服务器多了后,故障率也会上升。要么构建稳定的系统,要么构建发生故障时能自动切换以继续运行的系统!
低成本运维的重要性
采用自动化工具。
开发人数和开发方法的变化
如何标准化开发?
考虑下应用程序实现方案?
统一编程语言?
统一库函数和框架?
统一代码规范?
使用版本管理工具管理源代码?
须要有人负责全局的推行。
团队如何管理
应对大规模数据量
数据的流向:磁盘->内存->缓存->CPU。各层的速度差别巨大。
减少数据大小?
分散到多台服务器上?
把数据读取次数降到最低?
三、系统增加战略——最小化开端、预见变化的管理和设计
服务规模小的时候,使用简单的方法效果会更好。应该考虑某种程度上的容量规划,以及在设计服务时尽可能减小没必要要的数据等。
四、技术团队体制
服务开发部:负责开发各类服务的团队,负责平常的应用程序改进。内部按照服务分红团队,每队3~4人。服务开发部也会跟踪本身开发的服务的性能,将主要页面的大体响应时间定量化,而后天天改进。
基础设施部:负责运维服务器和基础设施的团队,负责准备服务器、运维数据中心和负载均衡等。
五、沟通方式
工做指示基本经过口头传达
若是口头效率低下或者但愿留下记录,则经过工具的组合来进行交流
博客+wiki(工做内、实施维护操做方法)
IRC
服务器管理工具
六、改变系统的流程
各团队用10分钟开个短会:共享前一天进度和当天计划。
会议中决定任务负责人,会议结束,当即开始任务。
实现过程尽可能书写测试用例。
测试以后开始实现,实现完成提交版本管理。
实现完成后,请求团队内其余开发工程师进行代码审查。
审查经过后,合并到产品代码。
七、数据规模
表的大小以GB为单位,执行select col from table,若是不加索引,由于数据量差很少有千万级别,所以,该SQL会卡死!因此哪怕是调试,也须要避免这种sql语句,可能会引发太高的负载。
八、处理难点
没法在内存中处理!须要读磁盘!内存要比磁盘的I/O快10W~100W倍。
磁盘的搜索和物理结构有关,搜索时有机械物理操做,须要数毫秒,可是内存搜索与物理结构无关,只须要数微秒。
由于磁盘搜索的慢,因此操做系统作了一些加速处理:
将连续的数据放在同一处,而后读取的时候并非逐个字节读取,而是一次读取4KB左右。(能够参考着看Linux相关基础,鸟哥私房菜里面也提到过。)这样就能够将旋转次数降到最低。
传输速度和总线速度的差别(上面说的是搜索!)。内存的传输速度大概比磁盘的快100倍。。。。。(可使用hdparm工具查看传输速度【Timing cached reads=内存传输速度】【Timing buffered disk reads=磁盘传输速度】)。
九、 可扩展性的要点——CPU负载和I/O负载
在web应用中,接受HTTP请求、查询数据库,再把数据库返回的数据加工变成HTML后发送给客户端,基本上只消耗CPU。相反,数据库服务器须要较多I/O资源。
由此,对于web应用程序服务器来讲,负载均衡很是简单,只须要相同的主机作相同的工做就能够实现了,由于不须要分散数据。可是I/O负载的负载均衡就没有那么简单了,由于数据分散以后就会有数据一致性的问题。
十、处理大规模数据的三个重点——写程序的技巧
能在内存中完成多少
在最大限度减小磁盘寻道次数的基础上灵活运用内存
充分利用局部性的分布式
使用能应对数据量增长的算法
例如线性搜索->二叉树搜索
O(n)->O(log n)
有时能够利用数据压缩和搜索等技术
十一、处理大规模数据以前的三大前提知识——程序开发的底层基础
操做系统的缓存
以分布式为前提应用RDBMS时必需要作的事
大规模环境中算法和数据结构怎样使用
十二、在理解操做系统缓存的基础上编写应用程序——页面缓存
linux上有页面缓存(page cache)、文件缓存(file cache)、缓冲区缓存(buffer cache)机制。
虚拟内存机制:将逻辑的线性地址变换成物理的物理地址。这样就可使进程无需考虑本身使用的内存位于什么地方,能够认为好比从0x000地址开始,这样处理就更方便。在分配内存时,以适当的大小(4KB)分配好,并传递给进程,而不是一个字节一个字节的访问。这样的内存块就称为“页面”。
页面缓存原理:操做系统可以让已分配的页面一直维持在这一状态。
进程不能访问磁盘,只能访问虚拟内存。
操做系统从磁盘中读取4KB的块,并写入到内存中,而后将该地址变换为虚拟地址后再告诉进程,最后进程再访问内存。而进程读完数据后,虽然再也不须要这块内存,可是并不会释放,而是保留下来,这样其余进程访问同一块磁盘时,就能够直接使用留下来的页面,无需再访问磁盘。这就是页面缓存。
页面缓存的效果就是,一直运行的操做系统更快些。
VFS
LINUX以页面为单位缓存磁盘
LRU
内存空闲时就缓存——经过sar确认:sar -r 1(每秒输出一次当前的内存状态),kbcached即用于缓存的容量,%memused被使用的内存,包括缓存。
增长内存下降I/O负载
1三、下降I/O负载的策略
以缓存为前提的下降I/O负载的策略
若是物理内存比数据规模还大,考虑所有缓存。
与经济成本的平衡性。
扩展到多台服务器——没法所有缓存的状况
CPU负载分散只须要简单的增长
I/O分散要考虑局部性
1四、利用局部性的分布式
局部性的分布式就是根据访问模式进行分散。
Partitioning——考虑局部性的分布式
Partitioning就是将一个数据库分割到多台服务器上。分割方法不少:
最简单的就是“以表为单位进行分割”,这种方式须要修改程序。
从数据的中间分割,例如按照ID的起始字母进行Partitioning。问题:当改变分割粒度时,须要将数据合并一次比较麻烦。
根据访问模式分割成“岛”——考虑局部性的分布式
好比通常用户分配到岛1,爬虫等分配到岛2
以页面缓存为基础的运维基本准则
操做系统刚启动时不要将服务器投入生产环境
性能测试要在缓存优化后进行
1五、分布式MySQL应用的三大要点
灵活应用操做系统缓存
正确应用索引
以横向扩展为前提设计系统
1六、灵活应用操做系统缓存
考虑全部数据的大小,尽可能将数据量维持在物理内存量之下。
内存不足时增长内存
考虑表结构设计对数据大小的影响
当记录数上亿以后,即便增长8字节的列,数据量也会增长3GB
规范化虽然能够减小数据量,可是会使查询变得复杂,所以应该在速度和数据量的平衡性前提下,考虑规范化。
1七、索引
B树
二叉树和B树:B树能够合理的设置节点大小,好比设置为4KB,则和上面的缓存大小相一致!
B+树
MySQL的索引采用的就是B+树:使得搜索外部设备时可以将寻道次数最小化;搜索复杂度O(n)->O(log n)
MySQL索引的不足
使用因此的有->where、order by、group by条件中指定的列
什么时候有效->明确的添加的索引;主键、UNIQUE约束。能够经过show index确认
MySQL索引的陷阱->想同时使用多个列上的索引,就必须使用复合索引
确认索引是否有效的方法——explain命令
type和rows:type为ALL,rows很大则索引无效,type为ref,rows比较小则索引有效
Extra列也十分重要,若是出现Using filesort或Using temporary的查询不能说是好查询
1八、MySQL的的分布式
MySQL的replication功能,即常见的主从和读写分离
应用程序服务器经过负载均衡去查询slave,这样就能够把查询分散到多台服务器上了。
master/slave的特征——对参照系进行扩展,更新类不扩展
主从的结构肯定了master是没法实现分布式的。
一般的应用程序,读占据了90%以上,所以master不会称为瓶颈。
须要对更新/写入类进行扩展——表分割、key-value存储
当master的表负载太高,则须要对表进行分割。经过分割来分散写入操做,若是能够分割表文件,就能够将其分散在同一台机器的多块硬盘或者分散到多台服务器上。
或者考虑不使用RDBMS,而使用key-value,如一般的点赞。
1九、MySQL的横向扩展策略
数据能放入内存吗?
->yes:放入内存
->no:增长内存,没法增长内存,则用Partitioning
分割以后,将没法使用join
以Partitioning为前提的设计
如若数据库表以前耦合性很是大,则设计时不要将其分割到不一样的服务器上。
避免join——利用where in
Partitioning的好处
下降负载
增长局部性
提升缓存的效果
缺点
运维变得复杂
故障率上升
实现冗余须要几台服务器
答:4台。1master+3slave。若是是1+2,假设slave坏掉,则在恢复数据的时候就必须停掉剩下那台slave!
20、特殊用途索引——处理大规模数据
超过RDBMS的处理能力时,利用批处理操做从RDBMS中提取出数据,创建索引服务器之类的东西,再让Web应用程序经过RPC等访问索引服务器。
特殊用途索引——使用调优后的数据结构
关键字连接的处理
使用巨大的正则表达式,虽然比数据库快,可是仍然很是慢
Trie+Common Prefix Search
2一、理论联系实践
探寻必须的技术条件
RDBMS中不使用JOIN,这应该是“最差实践”,教科书是绝对不会说不使用JION的,但这是从实践中得来的经验!
相反,使用一些教科书上的理论解决一些相应的问题,倒是十分正确的!
从计算机的角度去思考
后续是有关压缩、算法和搜索的话题
2二、以紧凑、简洁的方式保存整数数据
压缩大规模数据能够下降磁盘I/O。
2三、可变字节码和速度的感受
可变字节码——整数的编码方式
对例子进行编码实现
2四、算法的实用化
算法和算法的评测
数据规模和复杂化的差别
若是数据很小,则算法的复杂度也区分不出来,但随着数据规模变大,算法选择的差别性就愈来愈大!
算法的评测->复杂度
时间复杂度(执行时间、操做步骤数)、空间复杂度(内存使用量)
复杂度和常数项——评测很重要
常数项:算法实现中不依赖与输入大小,但却不得不执行的一类处理。
就算实现不复杂,CPU缓存是否容易生效、分支预测是否发生等计算机结构特色也会有影响,所以常数项可能会致使差距。
如一样是O(log n)复杂度的排序算法中,快速排序是最快的,由于它使得CPU缓存容易生效。
2五、关键字连接
2六、文章分类
2七、全文搜索技术的应用范围
2八、搜索系统的架构
2九、搜索引擎的内部结构
30、建立全文搜索
3一、企业软件vs.Web服务
应用范围上的差别
流量、增加度、可靠性、事务二者间差别较大。
Web服务的基础设施
低成本、高效率:不该当追求100%的可靠性
重视可扩展性、响应性方面的设计
Web服务的服务规格常常会发生变化
3二、云vs.自行构建基础设施
云计算特色就是价格便宜,可扩展性优秀。缺点:内存有上限和低速I/O,模糊不清的负载均衡器,时常停机
自行构建基础设施:硬件配置能够灵活调整;可以灵活应对服务的要求;能够控制瓶颈。
3三、层和扩展性
一台服务器能处理的流量极限
各层的可扩展性
web服务器可扩展比较容易,增长服务器便可
数据库服务器和文件服务器的扩展性相比较而言没有那么容易。
read和write相比较,read的分布式也比较容易实现。
最难的要数write的分布式
3四、掌握负载进行调优
可视化的管理界面,服务器管理工具。
测量负载的指标——平均负载、内存和CPU相关信息
经验来讲,平均负载的值不超过CPU的核数就没有问题。
根据用途进行调优
面向用户
面向爬虫
3五、保证冗余性
应用程序服务器通常采用负载均衡实现失败转移和失败恢复,让故障服务器自动下线,故障恢复以后再上线。
数据库服务器能够采用muti-master的方式。
存储服务器采用分布式文件系统。
3六、系统稳定化
留出必定余量!
系统的不稳定性
功能增长+内存泄漏:功能达不到理想的性能,致使总体负载上升,服务中止,使用的编程语言,也很难消除内存泄漏。
地雷:好比一篇文章有一万多个评论,若是没有考虑到这种状况,极有可能将评论数所有读取出来进行展现,会致使服务器性能降低甚至停机。
用户的访问模式:如连接被贴到著名网站,被大量用户访问致使系统停机。一般能够采用缓存服务器。
数据量增长
外部关联程序的增长
内存、硬盘故障
网卡故障
3七、系统稳定对策
维持适当余量,能够将70%做为分界线
消灭不稳定因素:下降SQL负载、减小内存泄漏、发生异常时的自律控制等
发生异常时的自律控制如自动DoS判断;自动重启服务器;自动终止耗时查询。
3八、提升硬件资源使用率
引入虚拟化技术
经过服务器管理工具在运营上发挥虚拟化的优点
虚拟化的额外开销
CPU大约2%~3%
内存性能10%
网络性能50%
I/O性能下降5%左右
3九、网络的分界点
超过1Gbps(从路由来看应该是30万pps)->PC路由器的极限
对策:采用多个PC路由;购买成品路由器
超越500台主机->一个子网的极限
子网、ARP表的极限
网络架构的层次化
一、最小的为访问层
二、上面的是分发层
三、最上方为核心层或OSPF层
全球化->一个数据中心的极限
对策:采用CDN
40、应对大规模服务须知
做业队列系统——TheSchwartz等
存储的选择——RDBMS、key-value等
缓存系统——Squid等
计算集群——Hadoop等