php3亿数据查询方案 php查询数据表( 七 )


国内一线互联网公司,大部分都是通过这种方式,来加快数据同步效率 。还有更为激进的做法,是直接解析binlog,忽略以表为单位,直接写入 。但是这种做法,实现复杂,使用范围就更受到限制,只能用于一些场景特殊的数据库中(没有表结构变更,表和表之间没有数据依赖等特殊表) 。
四、 在Web服务器和数据库之间建立缓存
实际上,解决大访问量的问题,不能仅仅着眼于数据库层面 。根据“二八定律”,80%的请求只关注在20%的热点数据上 。因此,我们应该建立Web服务器和数据库之间的缓存机制 。这种机制,可以用磁盘作为缓存,也可以用内存缓存的方式 。通过它们,将大部分的热点数据查询,阻挡在数据库之前 。
1. 页面静态化
用户访问网站的某个页面,页面上的大部分内容在很长一段时间内 , 可能都是没有变化的 。例如一篇新闻报道,一旦发布几乎是不会修改内容的 。这样的话,通过CGI生成的静态html页面缓存到Web服务器的磁盘本地 。除了第一次,是通过动态CGI查询数据库获取之外,之后都直接将本地磁盘文件返回给用户 。
在Web系统规模比较小的时候,这种做法看似完美 。但是 , 一旦Web系统规模变大 , 例如当我有100台的Web服务器的时候 。那样这些磁盘文件 , 将会有100份,这个是资源浪费,也不好维护 。这个时候有人会想 , 可以集中一台服务器存起来,呵呵,不如看看下面一种缓存方式吧 , 它就是这样做的 。
2. 单台内存缓存
通过页面静态化的例子中,我们可以知道将“缓存”搭建在Web机器本机是不好维护的,会带来更多问题(实际上,通过PHP的apc拓展,可通过Key/value操作Web服务器的本机内存) 。因此 , 我们选择搭建的内存缓存服务 , 也必须是一个独立的服务 。
内存缓存的选择,主要有redis/memcache 。从性能上说,两者差别不大,从功能丰富程度上说,Redis更胜一筹 。
3. 内存缓存集群
当我们搭建单台内存缓存完毕 , 我们又会面临单点故障的问题,因此,我们必须将它变成一个集群 。简单的做法 , 是给他增加一个slave作为备份机器 。但是,如果请求量真的很多,我们发现cache命中率不高,需要更多的机器内存呢?因此,我们更建议将它配置成一个集群 。例如,类似redis cluster 。
Redis cluster集群内的Redis互为多组主从,同时每个节点都可以接受请求,在拓展集群的时候比较方便 。客户端可以向任意一个节点发送请求 , 如果是它的“负责”的内容 , 则直接返回内容 。否则,查找实际负责Redis节点,然后将地址告知客户端,客户端重新请求 。
对于使用缓存服务的客户端来说,这一切是透明的 。
内存缓存服务在切换的时候,是有一定风险的 。从A集群切换到B集群的过程中,必须保证B集群提前做好“预热”(B集群的内存中的热点数据,应该尽量与A集群相同,否则,切换的一瞬间大量请求内容,在B集群的内存缓存中查找不到,流量直接冲击后端的数据库服务,很可能导致数据库宕机) 。
4. 减少数据库“写”
上面的机制,都实现减少数据库的“读”的操作,但是 , 写的操作也是一个大的压力 。写的操作 , 虽然无法减少 , 但是可以通过合并请求,来起到减轻压力的效果 。这个时候,我们就需要在内存缓存集群和数据库集群之间 , 建立一个修改同步机制 。
先将修改请求生效在cache中,让外界查询显示正常 , 然后将这些sql修改放入到一个队列中存储起来 , 队列满或者每隔一段时间,合并为一个请求到数据库中更新数据库 。

推荐阅读