到此为止,一共介绍了四种server性能优化的方法。各自是:动态内容缓存、浏览器缓存、反向代理缓存、Web组件分离。
我们发如今这四种方法中,“缓存”占了大头!
确实如此,“缓存”是server性能优化的核心思想。我们提出的各种优化方法本质上仅仅是把“缓存”用在了不同的地方。并依据使用位置的不同,个性化定制缓存的用法。接下来又要介绍一种缓存的新用法——数据缓冲区。
之前介绍的动态内容缓存、浏览器缓存都是将整个静态页面进行缓存。这样的方式有个弊端:因为缓存了总体页面,因此缓存的数据较为笨重。缺乏灵活性。为了解决问题。我们能够仅仅缓存数据库中的数据。当用户请求某一页面时。再依据用户的需求从数据缓存中抽出须要的数据。组装成页面返回给用户,从而提升了数据使用的灵活性
什么是数据缓冲区?数据缓冲区有啥优点?
我们能够在数据库之前开辟一块内存缓冲区,我们把这块区域称为数据缓冲区。
全部从数据库出来和进入的数据都要经过该缓冲区。
那么,数据想要进入数据库,首先须要进入缓冲区,当缓冲区存满时,一次性地写入数据库。从而减少了数据库操作的频率;同理,从数据库出来的数据也会进入该缓冲区,那么下次须要同样数据的时候直接从缓冲区中取就可以。
要知道,从内存中取数据要比从数据库中取数据快多了,因此缓冲区能大大提升数据插入和查询的性能。
怎样构建数据缓冲区?
依据刚才对缓冲区的介绍,我们能够将数据缓冲区分为:读缓冲和写缓冲。
- 读缓冲:用于存放即将被存入数据库的数据
- 写缓存:用于存放近期一段时间訪问频率较高的数据
使用Memcache实现数据缓冲区
这里我们使用memcache来实现数据缓冲区。
详细的Memcache的介绍请自行百度吧。这里简介下Memcache的几个优点:
- 查询效率高
Memcache採用健值对的形式存储数据,而且採用优化了的基于Key的Hash算法,因此无论Memcache中存储了多少数据。依据key查询value的时间复杂度永远是O(1)!
- 网络并发能力强
Memcache採用了libevent函数库来实现TCP通信,因此在较高并发数的情况下仍然能高效工作。
大家不用操心它的效率。
关于Memcache的使用请移步至:在Linux上安装Memcached服务
1. 构建写缓冲区
场景如果:实现点击量的记录
最Low的做法是每有一个用户点击,就把数据库中的相关值加1.但这样的每次更新数据库的做法显然不够高效。当訪问量非常大时,须要不断更新数据库。大大减少server的总体性能。
因此,訪问量的登记全然能够存入写缓存中,当訪问量存到1000时,一次性写入数据库,从而数据库更新频率从1000次减少到1次。大大节省了开销。
当然。使用缓存随之会带来数据实时性减少的问题。但对于像訪问量这样的无关紧要的数据来说,用减少实时性来换取server性能开销,还是相当划算的。
注意:小心线程安全问题!
要实现缓存中的指定页面的訪问量加一,一共须要三步:
- 将指定页面的当前訪问量取出来
- 訪问量加一
- 更新缓存中该页面的訪问量
因此。若多线程同一时候訪问,会出现线程安全问题。
因此我们须要使用memcache的原子加一操作(increment)来避免线程安全问题。
2. 构建读缓冲区
场景如果:检查用户是否登录
补充知识:怎样推断用户是否登录?
用户点击“记住password”后就不须要再输入password。那么当用户再次訪问站点时,server该怎样推断该用户是否已经登录呢?
在非常久曾经,用户登录之后server会在用户的Cookie中存放该用户的id。若用户再次訪问站点时,如果请求中包括用户id就觉得他已经登录,否则就须要又一次登录。
但这样的方法会引起安全隐患,因为id具有规律性,黑客往往会篡改他本地的Cookie来冒充其它用户登录。
为了避免这样的情况的发生。在用户注冊的时候,server会为每一个用户生成一个无规律的随机字符串ticket,用于标示该用户,并将其存入用户的Cookie。
因为字符串随机生成,没有了规律性,因此黑客没办法猜到其它用户的ticket。当用户每次訪问站点时。如果请求中携带了ticket,我们就查询数据库中是否存在该ticket,若存在则表示该用户已经登录。否则须要又一次登录。
那么问题来了,如果每次推断ticket是否存在都须要查询数据库的话。那么当用户量非常大的时候会影响server总体性能。因此我们能够将全部的ticket存入读缓存,并每隔一段时间更新。确保ticket的实时性。从而当用户訪问站点时,仅仅须要从读缓存中查询ticket是否存在就可以。无需查询数据库,从而节约了数据库开销。
怎样构建分布式数据缓冲区?
当一个memcache存不下全部缓存的时候,我们须要使用多个memcache来实现分布式数据缓冲区。
“分布式数据缓冲区”看似高大上。事实上非常easy。
如果如今有三台server上执行Memcache,IP各自是:
- 10.20.100.101
- 10.20.100.102
- 10.20.100.103
在存储之前,我们须要确定到底把数据存储在哪台缓存server上。我们希望数据能够平均地存储在三台server上,从而实现负载均衡。能够採用随机分配的方法:
- 将每一个请求的URL进行MD5运算,得到32字节的16进制数;
- 取前5位,模以3
- 得到的结果就是缓存server的ID
注:通过概率论能够证明。当訪问量非常大的时候。採用随机分配的方式能够保证每台缓存server被选中的次数是一样的。