Memcached

  曾经思考过OracleMysql这两种数据库的性能差别到底体现在哪里,给人直观的感觉是启动Oracle的服务会消耗大量的内存,在SQL Server2000上不存在这种内存消耗,可是到了SQL Server2005发现了跟Oracle同样的现象。其实稍微分析一下其中的原理,还是满简单的。

 

计算机发明以来就有内存和CPU的概念,CPU执行计算,内存存储数据。虽然CPU有指令寄存器等但从现在的硬件发展水平来看,影响计算机运行速度的主要是内存与磁盘的数据交换,换句话说如果程序需要的数据能直接从内存中读取到,而不是先从磁盘读取到内存的话,速度的提高将会很可观(基于CPU只能与内存数据交互这个事实)。

 

所以Oracle等数据库厂商会设计高深复杂的算法和管理策略,使得查询的数据尽量高效的留在内存中,所谓高效就是指这些内存中的数据都是频繁被使用的,那么每次去内存中直接读取数据的命中率就会很高,所以用命中率这个指标来评价缓存策略的效率是最合适的。

 

然而,这势必会带来一些技术上的难点:

1、  内存毕竟不如磁盘空间广阔,也不能所有数据都放入内存中,大小限制

2、  即使放入内存中的数据,也不是在任何时间内都属于高频率被访问的,有一种过期或者降级的概念

3、  数据存储的终端毕竟是磁盘,当做改动时如何同步到磁盘中

4、  内存也不是顺序存放的,依赖地址寻址,分区的策略和管理方式很难做到绝对的智能

 

所有这些讨论最终可以总结为两个字:“缓存”(Cache),下面说一说Memcached

Memcached也是最近做架构设计考虑到性能才学习到的一个概念,它是一种集中式Cache,支持分布式横向扩展。我们使用它的原因是服务器端用Java开发,数据会被读取到JVM分配的内存中,可是当服务端做了集群之后,每个集群的端点都是一个相对独立的JVM,它们之间无法轻易的看到对方JVM内存中的数据,或者说用Java序列化实现的话目的端JVM会存放一模一样的原对象副本,这样造成所有集群结点都具有一份数据对象的副本。

 

基于这种需求,采用Memcached可以满足需求,现在的MemCached Cache服务端是用C写的,只是对Java提供了接口。首先它的缓存分区独立于JVM,于是被不同JVM访问时可以摆脱JVM的边界约束,相当于一片独立的内存。配置两个或者多个客户端在一个集群中将数据放入任何一个集群的客户端中,都可以从其他集群中的客户端获取到数据(在获取数据时将会根据keyHash算法来选择集群的客户端为程序服务,实现类似于分布式节点的功能)

 

这是摘记的Cache机制:

有时候很多开源的项目做的面面俱到,但是最后也就是因为过于注重一些非必要性的功能而拖累了性能,这里要提到的就是Memcached的简单性。首先它没有什么同步,消息分发,两阶段提交等等,它就是一个很简单的Cache,把东西放进去,然后可以取出来,如果发现所提供的Key没有命中,那么就很直白的告诉你,你这个key没有任何对应的东西在缓存里,去数据库或者其他地方取,当你在外部数据源取到的时候,可以直接将内容置入到Cache中,这样下次就可以命中了。这里会提到怎么去同步这些数据,两种方式,一种就是在你修改了以后立刻更新Cache内容,这样就会即时生效。另一种是说容许有失效时间,到了失效时间,自然就会将内容删除,此时再去去的时候就会命中不了,然后再次将内容置入Cache,用来更新内容。后者用在一些时时性要求不高,写入不频繁的情况。

 

The End

Memcached是用C写的一个服务端,客户端没有规定,反正是Socket传输,只要语言支持Socket通信,通过Command的简单协议就可以通信,但是客户端设计的合理十分重要,同时也给使用者提供了很大的空间去扩展和设计客户端来满足各种场景的需要,包括容错,权重,效率,特殊的功能性需求,嵌入框架等等。内存存储,不言而喻,速度快,对于内存的要求高,不指出的话所缓存的内容非持久化。对于CPU要求很低,所以常常采用将Memcached服务端和一些CPU高消耗Memory低消耗应用部属在一起。



你可能感兴趣的:(jvm,oracle,sql,cache,server,集群,memcached)