嗨客网搜索
Memcached缓存

Memcached缓存

Memcached 的主要作用就是作为服务器端的缓存,将一些常用的数据缓存起来,以达到提高服务器的性能的目的。

Memcached缓存详解

相信大家都玩过一些网络联机游戏吧。在我那个年代(03 年左右),这些游戏常常添加了对战功能,并提供了天梯来显示具有最优秀战绩的玩家以及当前玩家在天梯系统中的排名。这是游戏开发商所常常采用的一种聚拢玩家人气的手段。而希望在游戏中证明自己的玩家则会由此激发斗志,进而花费更多时间来在天梯中取得更好的成绩。

就天梯系统来说,其最主要的功能就是为玩家提供天梯排名的信息,而并不允许玩家对该系统中所记录的数据作任何修改。这样设定的结果就是,整个天梯系统的读操作居多,而写操作很少。反过来,由于一个游戏中的玩家可能有上千万甚至上亿人,而且在线人数常常达到上万人,因此对天梯的访问也会是非常频繁的。这样的话,即使每秒钟只有10个人访问天梯中的排名,对这上亿个玩家的天梯排名进行读取及排序也是一件非常消耗性能的事情。

一个自然而然的想法就是:在对天梯排名进行一次计算后,我们在服务端将该天梯排名缓存起来,并在其它玩家访问的时候直接返回该缓存中所记录的结果。而在一定时间段之后,如一个小时,我们再对缓存中的数据进行更新。这样我们就不再需要每个小时执行成千上万次的天梯排名计算了。

而这就是服务端缓存所提供的最重要功能。其既可以提高单个请求的响应速度,又可以降低服务层及数据库层的压力。除此之外,多个服务实例都可以读取该服务端缓存所缓存的信息,因此我们也不再需要担心这些数据在各个服务实例中都保存了一份进而需要彼此同步的问题,也即是提高了扩展性。

而 Memcached 就是一个使用了 BSD 许可的服务端缓存实现。但是与其它服务端缓存实现不同的是,其主要由两部分组成:独立运行的 Memcached 服务实例,以及用于访问这些服务实例的客户端。因此相较于普通服务端缓存实现中各个缓存都运行在服务实例之上的情况,Memcached 服务实例则是在服务实例之外独立运行的:

01_Memcached缓存.png

从上图中可以看出,由于 Memcached 缓存实例是独立于各个应用服务器实例运行的,因此应用服务实例可以访问任意的缓存实例。而传统的缓存则与特定的应用实例绑定,因此每个应用实例将只能访问特定的缓存。这种绑定一方面会导致整个应用所能够访问的缓存容量变得很小,另一方面也可能导致不同的缓存实例中存在着冗余的数据,从而降低了缓存系统的整体效率。

在运行时,Memcached 服务实例只需要消耗非常少的 CPU 资源,却需要使用大量的内存。因此在决定如何组织您的服务端缓存结构之前,您首先需要搞清当前服务中各个服务实例的负载情况。如果一个服务器的 CPU 使用率非常高,却存在着非常多的空余内存,那么我们就完全可以在其上运行一个 Memcached 实例。而如果当前服务中的所有服务实例都没有过多的空余内存,那么我们就需要使用一系列独立的服务实例来搭建服务端缓存。一个大型服务常常拥有上百个 Memcached 实例。而在这上百个 Memcached 实例中所存储的数据则不尽相同。由于这种数据的异构性,我们需要在访问由 Memcached 所记录的信息之前决定在该服务端缓存系统中到底由哪个 Memcached 实例记录了我们所想要访问的数据:

02_Memcached缓存.png

如上图所示,用户需要通过一个 Memcached 客户端来完成对缓存服务所记录信息的访问。该客户端知道服务端缓存系统中所包含的所有 Memcached 服务实例。在需要访问具有特定键值的数据时,该客户端内部会根据所需要读取的数据的键值,如 “foo”,以及当前 Memcached 缓存服务的配置来计算相应的哈希值,以决定到底是哪个 Memcached 实例记录了用户所需要访问的信息。在决定记录了所需要信息的 Memcached 实例之后,Memcached 客户端将从配置中读取该 Memcached 服务实例所在地址,并向该 Memcached 实例发送数据访问请求,以从该 Memcached 实例中读取具有键值 “foo” 的信息。在各个论坛的讨论中,这被称为是 Memcached 的两阶段哈希(Two-stage hash)。

而对数据的记录也使用了类似的流程:假设用户希望通过服务端缓存记录数据 “bar”,并为其指定键值 “foo”。那么 Memcached 客户端将首先对用户所赋予的键值 “foo” 及当前服务端缓存所记录的可用服务实例个数执行哈希计算,并根据哈希计算结果来决定存储该数据的 Memcached 服务实例。接下来,客户端就会向该实例发送请求,以在其中记录具有键值 “foo” 的数据 “bar”。

这样做的好处则在于,每个 Memcached 服务实例都是独立的,而彼此之间并没有任何交互。在这种情况下,我们可以省略很多复杂的功能逻辑,如各个节点之间的数据同步以及结点之间消息的广播等等。这种轻量级的架构可以简化很多操作。如在一个节点失效的时候,我们仅仅需要使用一个新的 Memcached 节点替代老节点即可。而在对缓存进行扩容的时候,我们也只需要添加额外的服务并修改客户端配置。

这些记录在服务端缓存中的数据是全局可见的。也就是说,一旦在 Memcached 服务端缓存中成功添加了一条新的记录,那么其它使用该缓存服务的应用实例将同样可以访问该记录:

03_Memcached缓存.png

在 Memcached 中,每条记录都由四部分组成:记录的键,有效期,一系列可选的标记以及表示记录内容的数据。由于记录内容的数据中并不包含任何数据结构,因此我们在 Memcached 中所记录的数据需要是经过序列化之后的表示。

嗨客网顶部