优秀的缓存工具Memcached
Memcached介绍
基于对ERP项目的思考,我看看了关于缓存方面的东西。在所有的缓存方案中,Memcached是最让我有兴趣的。看看Memcached项目
的有关背景:
memcached is a high-performance, distributed memory object caching system, generic in nature, but intended
for use in speeding up dynamic web applications by alleviating database load.
Danga Interactive developed memcached to enhance the speed of LiveJournal.com,
a site which was already doing 20 million+ dynamic page views per day for 1 million users with a
bunch of webservers and a bunch of database servers. memcached dropped the database load to almost nothing,
yielding faster page load times for users, better resource utilization, and faster access to the databases
on a memcache miss.
不翻译了,只强调几个keywords:
high-performance,distributed memory
LiveJournal.com----------因为这个百万级的网站的需求而产生的。
1.high-performance
在官方wiki上有这么一句:
Very fast. It uses libevent to scale to any number of open connections (using epoll on Linux,
if available at runtime), uses non-blocking network I/O, refcounts internal objects (so objects
can be in multiple states to multiple clients), and uses its own slab allocator and hash table so
virtual memory never gets externally fragmented and allocations are guaranteed O(1).
使用libevent,它可以应对任意多个连接,使用非阻塞的网络IO.
由于它的工作机制是在内存中开辟一块空间,然后建立一个HashTable,Memcached自管理这些HashTable。
由于是对HashTable的遍历,所以其查询复杂度是O(1)。
至于其中提到的libevent,呵呵,还没有看:)
2.distributed memory:分布式的内存管理,这正式它的优势所在。Memcached Client API 屏蔽了对象在不同内存区域的差别,
以一致的接口方法,所以用起来你完全感觉不到在使用不同的内存对象,当然缓存的时候也感觉不到。
这也是系统水平扩展的一个要点。理论上内存可以无限扩展,只要平行增加server节点就可以。
3.和数据库缓存的比较:
不考虑使用什么样的数据库(MS-SQL, Oracle, Postgres, MysQL-InnoDB, etc..),
实现事务(ACID,Atomicity, Consistency, Isolation, and Durability )需要大量开销,
特别当使用到硬盘的时候,意味着查询可能会阻塞。当使用不包含事务的数据库(例如Mysql-MyISAM),上面的开销不存在,但读线程又可能会被写线程阻塞。
可以看出,用数据库做缓存,在很大程度上是不明智的。
4. 和共享内存的比较:
最初的缓存做法是在线程内对对象进行缓存,但这样进程间就无法共享缓存,命中率非常低,导致缓存效率极低。
后来出现了共享内存的缓存,多个进程或者线程共享同一块缓存,但毕竟还是只能局限在一台机器上,多台机器做相
同的缓存同样是一种资源的浪费,而且命中率也比较低。 Memcached Server和Clients共同工作,实现跨服务器
分布式的全局的缓存。并且可以与Web Server共同工作,Web Server对CPU要求高,对内存要求低,
Memcached Server对CPU要求低,对内存要求高,所以可以搭配使用。
5. 缓存对象同步管理:
Memcached是遵循LRU(Least Recently Used:最近最少被使用)原则。当然你也可以设置缓存对象的生命周期。
6.Memcached的使用(Win32,.Net)
具体下载安装过程:http://jehiah.cz/projects/memcached-win32/
在win32下,memcached就是一个windows service。你可以在windows服务中找到:memcached Server 。这个就是了。
发现这玩意比较消耗内存。
.Net中使用:
引用Memcached.ClientLibrary.dll,主要使用其中的几个类:
Memcached.ClientLibrary.SockIOPool pool = Memcached.ClientLibrary.SockIOPool.GetInstance(); ---服务器管理对象
MemcachedClient mc = new MemcachedClient(); ---客户端
比较感兴趣这个GetInstance方法,具体看看:
pool.SetServers(serverlist);
pool.InitConnections = 3;
pool.MinConnections = 3;
pool.MaxConnections = 5;
上面的代码,可以看到server的配置还是很强的。至于利用client api开发则是相当简单。自带的MemCachedBench_2.0项目就是相当好的一个demo。
有空翻译下:http://www.linuxjournal.com/article/7451
基于对ERP项目的思考,我看看了关于缓存方面的东西。在所有的缓存方案中,Memcached是最让我有兴趣的。看看Memcached项目
的有关背景:
memcached is a high-performance, distributed memory object caching system, generic in nature, but intended
for use in speeding up dynamic web applications by alleviating database load.
Danga Interactive developed memcached to enhance the speed of LiveJournal.com,
a site which was already doing 20 million+ dynamic page views per day for 1 million users with a
bunch of webservers and a bunch of database servers. memcached dropped the database load to almost nothing,
yielding faster page load times for users, better resource utilization, and faster access to the databases
on a memcache miss.
不翻译了,只强调几个keywords:
high-performance,distributed memory
LiveJournal.com----------因为这个百万级的网站的需求而产生的。
1.high-performance
在官方wiki上有这么一句:
Very fast. It uses libevent to scale to any number of open connections (using epoll on Linux,
if available at runtime), uses non-blocking network I/O, refcounts internal objects (so objects
can be in multiple states to multiple clients), and uses its own slab allocator and hash table so
virtual memory never gets externally fragmented and allocations are guaranteed O(1).
使用libevent,它可以应对任意多个连接,使用非阻塞的网络IO.
由于它的工作机制是在内存中开辟一块空间,然后建立一个HashTable,Memcached自管理这些HashTable。
由于是对HashTable的遍历,所以其查询复杂度是O(1)。
至于其中提到的libevent,呵呵,还没有看:)
2.distributed memory:分布式的内存管理,这正式它的优势所在。Memcached Client API 屏蔽了对象在不同内存区域的差别,
以一致的接口方法,所以用起来你完全感觉不到在使用不同的内存对象,当然缓存的时候也感觉不到。
这也是系统水平扩展的一个要点。理论上内存可以无限扩展,只要平行增加server节点就可以。
3.和数据库缓存的比较:
不考虑使用什么样的数据库(MS-SQL, Oracle, Postgres, MysQL-InnoDB, etc..),
实现事务(ACID,Atomicity, Consistency, Isolation, and Durability )需要大量开销,
特别当使用到硬盘的时候,意味着查询可能会阻塞。当使用不包含事务的数据库(例如Mysql-MyISAM),上面的开销不存在,但读线程又可能会被写线程阻塞。
可以看出,用数据库做缓存,在很大程度上是不明智的。
4. 和共享内存的比较:
最初的缓存做法是在线程内对对象进行缓存,但这样进程间就无法共享缓存,命中率非常低,导致缓存效率极低。
后来出现了共享内存的缓存,多个进程或者线程共享同一块缓存,但毕竟还是只能局限在一台机器上,多台机器做相
同的缓存同样是一种资源的浪费,而且命中率也比较低。 Memcached Server和Clients共同工作,实现跨服务器
分布式的全局的缓存。并且可以与Web Server共同工作,Web Server对CPU要求高,对内存要求低,
Memcached Server对CPU要求低,对内存要求高,所以可以搭配使用。
5. 缓存对象同步管理:
Memcached是遵循LRU(Least Recently Used:最近最少被使用)原则。当然你也可以设置缓存对象的生命周期。
6.Memcached的使用(Win32,.Net)
具体下载安装过程:http://jehiah.cz/projects/memcached-win32/
在win32下,memcached就是一个windows service。你可以在windows服务中找到:memcached Server 。这个就是了。
发现这玩意比较消耗内存。
.Net中使用:
引用Memcached.ClientLibrary.dll,主要使用其中的几个类:
Memcached.ClientLibrary.SockIOPool pool = Memcached.ClientLibrary.SockIOPool.GetInstance(); ---服务器管理对象
MemcachedClient mc = new MemcachedClient(); ---客户端
比较感兴趣这个GetInstance方法,具体看看:
1 // empty constructor
2 protected SockIOPool() { }
3
4 /// <summary>
5 /// Factory to create/retrieve new pools given a unique poolName.
6 /// </summary>
7 /// <param name="poolName">unique name of the pool</param>
8 /// <returns>instance of SockIOPool</returns>
9 [MethodImpl(MethodImplOptions.Synchronized)]
10 public static SockIOPool GetInstance(String poolName)
11 {
12 if(Pools.ContainsKey(poolName))
13 return (SockIOPool)Pools[poolName];
14
15 SockIOPool pool = new SockIOPool();
16 Pools[poolName] = pool;
17
18 return pool;
19 }
20
21 /// <summary>
22 /// Single argument version of factory used for back compat.
23 /// Simply creates a pool named "default".
24 /// </summary>
25 /// <returns>instance of SockIOPool</returns>
26 [MethodImpl(MethodImplOptions.Synchronized)]
27 public static SockIOPool GetInstance()
28 {
29 return GetInstance(GetLocalizedString("default instance"));
30 }
string[] serverlist = { "192.168.100.142:11211" };2 protected SockIOPool() { }
3
4 /// <summary>
5 /// Factory to create/retrieve new pools given a unique poolName.
6 /// </summary>
7 /// <param name="poolName">unique name of the pool</param>
8 /// <returns>instance of SockIOPool</returns>
9 [MethodImpl(MethodImplOptions.Synchronized)]
10 public static SockIOPool GetInstance(String poolName)
11 {
12 if(Pools.ContainsKey(poolName))
13 return (SockIOPool)Pools[poolName];
14
15 SockIOPool pool = new SockIOPool();
16 Pools[poolName] = pool;
17
18 return pool;
19 }
20
21 /// <summary>
22 /// Single argument version of factory used for back compat.
23 /// Simply creates a pool named "default".
24 /// </summary>
25 /// <returns>instance of SockIOPool</returns>
26 [MethodImpl(MethodImplOptions.Synchronized)]
27 public static SockIOPool GetInstance()
28 {
29 return GetInstance(GetLocalizedString("default instance"));
30 }
pool.SetServers(serverlist);
pool.InitConnections = 3;
pool.MinConnections = 3;
pool.MaxConnections = 5;
上面的代码,可以看到server的配置还是很强的。至于利用client api开发则是相当简单。自带的MemCachedBench_2.0项目就是相当好的一个demo。
有空翻译下:http://www.linuxjournal.com/article/7451
posted on 2007-07-24 17:44 flyingchen 阅读(4069) 评论(6) 编辑 收藏 举报