《大规模WEB服务开发技术》读书笔记(I)

1、认识服务的规模

注册用户,独立用户

请求数

繁忙时流量

服务器台数

貌似应该有很多其他的指标,以前都听说过,但是从来没有认真分析过,已经上线的系统也没有对此进行过统计和分析!

2、大规模服务中的问题有以下几点:

可扩展性、负载均衡的必要性

一般来说,当一台服务器无法承担负载时,都会采用横向扩展(scale out)或者纵向扩展(scale up)。横向扩展就是通过服务器的数量来分担负载,纵向扩展是通过提高硬件的性能来处理负载。而我们知道,硬件的性能和价格不是成比例的,所以通常采用横向扩展技术!采用横向扩展也会带来问题,如请求如何分配——负载均衡,数据如何同步,网络通信延迟等。

保证冗余性

服务器多了后,故障率也会上升。要么构建稳定的系统,要么构建发生故障时能自动切换以继续运行的系统!

低成本运维的重要性

采用自动化工具。

开发人数和开发方法的变化

如何标准化开发?

考虑下应用程序实现方案?

统一编程语言?

统一库函数和框架?

统一代码规范?

使用版本管理工具管理源代码?

需要有人负责全局的推行。

团队如何管理

应对大规模数据量

数据的流向:磁盘->内存->缓存->CPU。各层的速度差异巨大。

减小数据大小?

分散到多台服务器上?

把数据读取次数降到最低?

3、系统增长战略——最小化开端、预见变化的管理和设计

服务规模小的时候,使用简单的方法效果会更好。应该考虑某种程度上的容量规划,以及在设计服务时尽量减少不必要的数据等。

4、技术团队体制

服务开发部:负责开发各种服务的团队,负责日常的应用程序改进。内部按照服务分成团队,每队3~4人。服务开发部也会跟踪自己开发的服务的性能,将主要页面的大致响应时间定量化,然后每天改进。

基础设施部:负责运维服务器和基础设施的团队,负责准备服务器、运维数据中心和负载均衡等。

5、沟通方式

工作指示基本通过口头传达

如果口头效率低下或者希望留下记录,则通过工具的组合来进行交流

博客+wiki(工作内、实施维护操作方法)

IRC

服务器管理工具

6、改变系统的流程

各团队用10分钟开个短会:共享前一天进度和当天计划。

会议中决定任务负责人,会议结束,立即开始任务。

实现过程尽量书写测试用例。

测试之后开始实现,实现完成提交版本管理。

实现完成后,请求团队内其他开发工程师进行代码审查。

审查通过后,合并到产品代码。

7、数据规模

表的大小以GB为单位,执行select col from table,如果不加索引,因为数据量差不多有千万级别,因此,该SQL会卡死!所以哪怕是调试,也需要避免这种sql语句,可能会引起过高的负载。

8、处理难点

无法在内存中处理!需要读磁盘!内存要比磁盘的I/O快10W~100W倍。

磁盘的搜索和物理结构有关,搜索时有机械物理操作,需要数毫秒,但是内存搜索与物理结构无关,只需要数微秒。

因为磁盘搜索的慢,所以操作系统做了一些加速处理:

将连续的数据放在同一处,然后读取的时候并不是逐个字节读取,而是一次读取4KB左右。(可以参考着看Linux相关基础,鸟哥私房菜里面也提到过。)这样就可以将旋转次数降到最低。

传输速度和总线速度的差异(上面说的是搜索!)。内存的传输速度大概比磁盘的快100倍。。。。。(可以使用hdparm工具查看传输速度【Timing cached reads=内存传输速度】【Timing buffered disk reads=磁盘传输速度】)。

9、 可扩展性的要点——CPU负载和I/O负载

在web应用中,接受HTTP请求、查询数据库,再把数据库返回的数据加工变成HTML后发送给客户端,基本上只消耗CPU。相反,数据库服务器需要较多I/O资源。

由此,对于web应用程序服务器来说,负载均衡非常简单,只需要相同的主机做相同的工作就可以实现了,因为不需要分散数据。但是I/O负载的负载均衡就没有那么简单了,因为数据分散之后就会有数据一致性的问题。

10、处理大规模数据的三个重点——写程序的技巧

能在内存中完成多少

在最大限度减少磁盘寻道次数的基础上灵活运用内存

充分利用局部性的分布式

使用能应对数据量增加的算法

例如线性搜索->二叉树搜索

O(n)->O(log n)

有时可以利用数据压缩和搜索等技术

11、处理大规模数据之前的三大前提知识——程序开发的底层基础

操作系统的缓存

以分布式为前提应用RDBMS时必须要做的事

大规模环境中算法和数据结构怎样使用

12、在理解操作系统缓存的基础上编写应用程序——页面缓存

linux上有页面缓存(page cache)、文件缓存(file cache)、缓冲区缓存(buffer cache)机制。

虚拟内存机制:将逻辑的线性地址变换成物理的物理地址。这样就可以使进程无需考虑自己使用的内存位于什么地方,可以认为比如从0x000地址开始,这样处理就更方便。在分配内存时,以适当的大小(4KB)分配好,并传递给进程,而不是一个字节一个字节的访问。这样的内存块就称为“页面”。

页面缓存原理:操作系统能够让已分配的页面一直维持在这一状态。

进程不能访问磁盘,只能访问虚拟内存。

操作系统从磁盘中读取4KB的块,并写入到内存中,然后将该地址变换为虚拟地址后再告诉进程,最后进程再访问内存。而进程读完数据后,虽然不再需要这块内存,但是并不会释放,而是保留下来,这样其他进程访问同一块磁盘时,就可以直接使用留下来的页面,无需再访问磁盘。这就是页面缓存。

页面缓存的效果就是,一直运行的操作系统更快些。

VFS

LINUX以页面为单位缓存磁盘

LRU

内存空闲时就缓存——通过sar确认:sar -r 1(每秒输出一次当前的内存状态),kbcached即用于缓存的容量,%memused被使用的内存,包括缓存。

增加内存降低I/O负载

13、降低I/O负载的策略

以缓存为前提的降低I/O负载的策略

如果物理内存比数据规模还大,考虑全部缓存。

与经济成本的平衡性。

扩展到多台服务器——无法全部缓存的情况

CPU负载分散只需要简单的增加

I/O分散要考虑局部性

14、利用局部性的分布式

局部性的分布式就是根据访问模式进行分散。

Partitioning——考虑局部性的分布式

Partitioning就是将一个数据库分割到多台服务器上。分割方法很多:

最简单的就是“以表为单位进行分割”,这种方式需要修改程序。

从数据的中间分割,例如按照ID的起始字母进行Partitioning。问题:当改变分割粒度时,需要将数据合并一次比较麻烦。

根据访问模式分割成“岛”——考虑局部性的分布式

比如一般用户分配到岛1,爬虫等分配到岛2

以页面缓存为基础的运维基本准则

操作系统刚启动时不要将服务器投入生产环境

性能测试要在缓存优化后进行

15、分布式MySQL应用的三大要点

灵活应用操作系统缓存

正确应用索引

以横向扩展为前提设计系统

16、灵活应用操作系统缓存

考虑所有数据的大小,尽量将数据量维持在物理内存量之下。

内存不足时增加内存

考虑表结构设计对数据大小的影响

当记录数上亿之后,即使增加8字节的列,数据量也会增加3GB

规范化虽然可以减少数据量,但是会使查询变得复杂,因此应该在速度和数据量的平衡性前提下,考虑规范化。

17、索引

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的查询不能说是好查询

18、MySQL的的分布式

MySQL的replication功能,即常见的主从和读写分离

应用程序服务器通过负载均衡去查询slave,这样就可以把查询分散到多台服务器上了。

master/slave的特征——对参照系进行扩展,更新类不扩展

主从的结构确定了master是无法实现分布式的。

通常的应用程序,读占据了90%以上,因此master不会称为瓶颈。

需要对更新/写入类进行扩展——表分割、key-value存储

当master的表负载过高,则需要对表进行分割。通过分割来分散写入操作,如果可以分割表文件,就可以将其分散在同一台机器的多块硬盘或者分散到多台服务器上。

或者考虑不使用RDBMS,而使用key-value,如通常的点赞。

19、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

21、理论联系实践

探寻必须的技术条件

RDBMS中不使用JOIN,这应该是“最差实践”,教科书是绝对不会说不使用JION的,但这是从实践中得来的经验!

相反,使用一些教科书上的理论解决一些相应的问题,却是十分正确的!

从计算机的角度去思考


后续是有关压缩、算法和搜索的话题

22、以紧凑、简洁的方式保存整数数据

压缩大规模数据可以降低磁盘I/O。

23、可变字节码和速度的感觉

可变字节码——整数的编码方式

对例子进行编码实现

24、算法的实用化

算法和算法的评测

数据规模和复杂化的差异

如果数据很小,则算法的复杂度也区分不出来,但随着数据规模变大,算法选择的差异性就越来越大!

算法的评测->复杂度

时间复杂度(执行时间、操作步骤数)、空间复杂度(内存使用量)

复杂度和常数项——评测很重要

常数项:算法实现中不依赖与输入大小,但却不得不执行的一类处理。

就算实现不复杂,CPU缓存是否容易生效、分支预测是否发生等计算机结构特点也会有影响,因此常数项可能会导致差距。

如同样是O(log n)复杂度的排序算法中,快速排序是最快的,因为它使得CPU缓存容易生效。

25、关键字链接

26、文章分类

27、全文搜索技术的应用范围

28、搜索系统的架构

29、搜索引擎的内部结构

30、创建全文搜索

31、企业软件vs.Web服务

应用范围上的差异

流量、增长度、可靠性、事务两者间差异较大。

Web服务的基础设施

低成本、高效率:不应当追求100%的可靠性

重视可扩展性、响应性方面的设计

Web服务的服务规格经常会发生变化

32、云vs.自行构建基础设施

云计算特点就是价格便宜,可扩展性优秀。缺点:内存有上限和低速I/O,模糊不清的负载均衡器,时常停机

自行构建基础设施:硬件配置可以灵活调整;能够灵活应对服务的要求;可以控制瓶颈。

33、层和扩展性

一台服务器能处理的流量极限

各层的可扩展性

web服务器可扩展比较容易,增加服务器即可

数据库服务器和文件服务器的扩展性相比较而言没有那么容易。

read和write相比较,read的分布式也比较容易实现。

最难的要数write的分布式

34、掌握负载进行调优

可视化的管理界面,服务器管理工具。

测量负载的指标——平均负载、内存和CPU相关信息

经验来说,平均负载的值不超过CPU的核数就没有问题。

根据用途进行调优

面向用户

面向爬虫

35、保证冗余性

应用程序服务器一般采用负载均衡实现失败转移和失败恢复,让故障服务器自动下线,故障恢复之后再上线。

数据库服务器可以采用muti-master的方式。

存储服务器采用分布式文件系统。

36、系统稳定化

留出一定余量!

系统的不稳定性

功能增加+内存泄漏:功能达不到理想的性能,导致整体负载上升,服务停止,使用的编程语言,也很难消除内存泄漏。

地雷:比如一篇文章有一万多个评论,如果没有考虑到这种情况,极有可能将评论数全部读取出来进行展示,会导致服务器性能下降甚至停机。

用户的访问模式:如链接被贴到著名网站,被大量用户访问导致系统停机。通常可以采用缓存服务器。

数据量增加

外部关联程序的增加

内存、硬盘故障

网卡故障

37、系统稳定对策

维持适当余量,可以将70%作为分界线

消灭不稳定因素:降低SQL负载、减少内存泄漏、发生异常时的自律控制等

发生异常时的自律控制如自动DoS判断;自动重启服务器;自动终止耗时查询。

38、提高硬件资源使用率

引入虚拟化技术

通过服务器管理工具在运营上发挥虚拟化的优势

虚拟化的额外开销

CPU大约2%~3%

内存性能10%

网络性能50%

I/O性能降低5%左右

39、网络的分界点

超过1Gbps(从路由来看应该是30万pps)->PC路由器的极限

对策:采用多个PC路由;购买成品路由器

超越500台主机->一个子网的极限

子网、ARP表的极限

网络架构的层次化

1、最小的为访问层

2、上面的是分发层

3、最上方为核心层或OSPF层

全球化->一个数据中心的极限

对策:采用CDN

40、应对大规模服务须知

作业队列系统——TheSchwartz等

存储的选择——RDBMS、key-value等

缓存系统——Squid等

计算集群——Hadoop等



你可能感兴趣的:(《大规模WEB服务开发技术》读书笔记(I))