php如何分留数据 php对数据进行分组( 四 )


刚刚我们讲完了Web系统的外部网络环境 , 现在我们开始关注我们Web系统自身的性能问题 。我们的Web站点随着访问量的上升,会遇到很多的挑战 , 解决这些问题不仅仅是扩容机器这么简单,建立和使用合适的缓存机制才是根本 。
最开始,我们的Web系统架构可能是这样的,每个环节,都可能只有1台机器 。
我们从最根本的数据存储开始看哈 。
一、 MySQL数据库内部缓存使用
MySQL的缓存机制,就从先从MySQL内部开始,下面的内容将以最常见的InnoDB存储引擎为主 。
1. 建立恰当的索引
最简单的是建立索引,索引在表数据比较大的时候,起到快速检索数据的作用,但是成本也是有的 。首先,占用了一定的磁盘空间,其中组合索引最突出,使用需要谨慎,它产生的索引甚至会比源数据更大 。其次 , 建立索引之后的数据insert/update/delete等操作,因为需要更新原来的索引 , 耗时会增加 。当然,实际上我们的系统从总体来说,是以select查询操作居多,因此,索引的使用仍然对系统性能有大幅提升的作用 。
2. 数据库连接线程池缓存
如果,每一个数据库操作请求都需要创建和销毁连接的话,对数据库来说,无疑也是一种巨大的开销 。为了减少这类型的开销,可以在MySQL中配置thread_cache_size来表示保留多少线程用于复用 。线程不够的时候,再创建 , 空闲过多的时候,则销毁 。
其实,还有更为激进一点的做法 , 使用pconnect(数据库长连接),线程一旦创建在很长时间内都保持着 。但是,在访问量比较大 , 机器比较多的情况下,这种用法很可能会导致“数据库连接数耗尽”,因为建立连接并不回收,最终达到数据库的max_connections(最大连接数) 。因此,长连接的用法通常需要在CGI和MySQL之间实现一个“连接池”服务,控制CGI机器“盲目”创建连接数 。
建立数据库连接池服务 , 有很多实现的方式 , PHP的话 , 我推荐使用swoole(PHP的一个网络通讯拓展)来实现 。
3. Innodb缓存设置(innodb_buffer_pool_size)
innodb_buffer_pool_size这是个用来保存索引和数据的内存缓存区,如果机器是MySQL独占的机器 , 一般推荐为机器物理内存的80% 。在取表数据的场景中,它可以减少磁盘IO 。一般来说,这个值设置越大,cache命中率会越高 。
4. 分库/分表/分区 。
MySQL数据库表一般承受数据量在百万级别,再往上增长,各项性能将会出现大幅度下降 , 因此,当我们预见数据量会超过这个量级的时候,建议进行分库/分表/分区等操作 。最好的做法 , 是服务在搭建之初就设计为分库分表的存储模式,从根本上杜绝中后期的风险 。不过,会牺牲一些便利性,例如列表式的查询,同时,也增加了维护的复杂度 。不过,到了数据量千万级别或者以上的时候,我们会发现,它们都是值得的 。
二、 MySQL数据库多台服务搭建
1台MySQL机器,实际上是高风险的单点 , 因为如果它挂了,我们Web服务就不可用了 。而且 , 随着Web系统访问量继续增加 , 终于有一天,我们发现1台MySQL服务器无法支撑下去,我们开始需要使用更多的MySQL机器 。当引入多台MySQL机器的时候,很多新的问题又将产生 。
1. 建立MySQL主从,从库作为备份
这种做法纯粹为了解决“单点故障”的问题,在主库出故障的时候,切换到从库 。不过,这种做法实际上有点浪费资源,因为从库实际上被闲着了 。
2. MySQL读写分离 , 主库写,从库读 。

推荐阅读