专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »web服务器 » memcached:利用Memcached构建高性能的Web应用程序 »正文

memcached:利用Memcached构建高性能的Web应用程序

来源: 发布时间:星期日, 2009年1月4日 浏览:2次 评论:0
工作原理:

Memcached处理原子是每个(keyvalue)对(以下简称kv对)key会通过个hash算法转化成hash-key便于查找、对比以及做到尽可能散列同时memcached用个 2级散列通过张大hash表来维护

Memcached有两个核心组件组成:服务端(ms)和客户端(mc)个memcached查询中mc先通过计算keyhash值来确定kv对所处在ms位置当ms确定后客户端就会发送个查询请求给对应ms让它来查找确切数据这的间没有交互以及多播协议所以 memcached交互带给网络影响是最小化

举例介绍说明:考虑以下这个场景有 3个mc分别是XYZ还有 3个ms分别是ABC:

设置kv对
X想设置key=”foo”,value=”seattle”
X拿到ms列表并对key做hash转化根据hash值确定kv对所存ms位置
B被选中了
X连接上BB收到请求把(key=”foo”,value=”seattle”)存了起来

获取kv对
Z想得到key=”foo”value
Z用相同hash算法算出hash值并确定key=”foo”值存在B上
Z连接上B并从B那边得到value=”seattle”
其他任何从XYZ想得到key=”foo”请求都会发向B

="alignnone size-medium wp-image-85" height=423 alt="" src="http://www.crazycoder.cn/WebFiles/20091/cb3c679f-f42a-4e38-952a-40475b08c2b9.jpg" width=355>

Memcached服务器(ms)


内存分配

默认情况下ms是用个内置叫“块分配器”组件来分配内存舍弃c标准malloc/free内存分配而采用块分配器主要目是为了避免内存碎片否则操作系统要花费更多时间来查找这些逻辑上连续内存块(实际上是断开)用了块分配器ms会轮流对内存进行大块分配并不断重用当然由于块大小各不相同当数据大小和块大小不太相符情况下还是有可能导致内存浪费

同时ms对key和data都有相应限制key长度不能超过250字节data也不能超过块大小限制 --- 1MB
mc所使用hash算法并不会考虑到每个ms内存大小理论上mc会分配概率上等量kv对给每个ms这样如果每个ms内存都不太那可能会导致内存使用率降低所以种替代解决方案是根据每个ms内存大小找出他们最大公约数然后在每个ms上开n个容量=最大公约数 instance这样就等于拥有了多个容量大小子ms从而提供整体内存使用率

缓存Cache策略

当mshash表满了的后插入数据会替代老数据更新策略是LRU(最近最少使用)以及每个kv对有效时限Kv对存储有效时限是在mc端由app设置并作为参数传给ms

同时ms采用是偷懒替代法ms不会开额外进程来实时监测过时kv对并删除而是当且仅当新来个插入数据而此时又没有多余空间放了才会进行清除动作

缓存Cache数据库查询
现在memcached最流行种使用方式是缓存Cache数据库查询下面举个简单例子介绍说明:

App需要得到userid=xxx用户信息对应查询语句类似:

“SELECT * FROM users WHERE userid = xxx”

App先去问cache有没有“user:userid”(key定义可预先定义约束好)数据如果有返回数据;如果没有App会从数据库中读取数据cacheadd把数据加入cache中

当取数据需要更新app会cacheupdate来保持数据库和cache数据同步

从上面例子我们也可以发现旦数据库数据发现变化我们定要及时更新cache中数据来保证app读到是同步正确数据当然我们可以通过定时器方式记录下cache中数据失效时间时间过就会激发事件对cache进行更新但这的间总会有时间上延迟导致app可能从 cache读到脏数据这也被称为狗洞问题(以后我会专门描述研究这个问题)

数据冗余和故障预防

从设计角度上memcached是没有数据冗余环节它本身就是个大规模高性能cache层加入数据冗余所能带来只有设计复杂性和提高系统开支

个ms上丢失了数据的后app还是可以从数据库中取得数据不过更谨慎做法是在某些ms不能正常工作时提供额外ms来支持cache这样就不会app从cache中取不到数据而下子给数据库带来过大负载

同时为了减少某台ms故障所带来影响可以使用“热备份”方案就是用台新ms来取代有问题ms当然新ms还是要用原来msIP地址大不了数据重新装载

另外种方式就是提高你ms节点数然后mc会实时侦查每个节点状态如果发现某个节点长时间没有响应就会从mc可用server列表里删除并对server节点进行重新hash定位当然这样也会造成问题是原本key存储在B上变成存储在C上了所以此方案本身也有其弱点最好能和“热备份”方案结合使用就可以使故障造成影响最小化

Memcached客户端(mc)

Memcached客户端有各种语言版本供大家使用包括javacphp.net等等具体可参见memcached api page[2]
大家可以根据自己项目需要选择合适客户端来集成

缓存Cache式Web应用架构
有了缓存Cache支持我们可以在传统app层和db层的间加入cache层每个app服务器都可以绑定个mc每次数据读取都可以从ms中取得如果没有再从db层读取而当数据要进行更新时除了要发送update sql给db层同时也要将更新数据发给mc让mc去更新ms中数据

="alignnone size-medium wp-image-86" height=459 alt="" src="http://www.crazycoder.cn/WebFiles/20091/8a5c6773-a907-4a8a-a428-2c7a17270267.jpg" width=556>

假设今后我们数据库可以和ms进行通讯了那可以将更新任务统交给db层每次数据库更新数据同时会自动去更新ms中数据这样就可以进步减少app层逻辑复杂度如下图:

="alignnone size-medium wp-image-87" height=459 alt="" src="http://www.crazycoder.cn/WebFiles/20091/afd76f69-b4ef-42fa-8fd4-1f34cf02f8b6.jpg" width=556>

不过每次我们如果没有从cache读到数据都不得不麻烦数据库为了最小化数据库负载压力我们可以部署数据库复写用slave数据库来完成读取操作而master数据库永远只负责 3件事:1.更新数据;2.同步slave数据库;3.更新cache如下图:

="alignnone size-medium wp-image-96" height=417 alt="" src="http://www.crazycoder.cn/WebFiles/20091/2a768611-4d1a-4f46-9d63-2a98653258f7.jpg" width=555>

以上这些缓存Cache式web架构在实际应用中被证明是能有效并能极大地降低数据库负载同时又能提高web运行性能当然这些架构还可以根据具体应用环境进行变种以达到区别硬件条件下性能最优化

未来憧憬
Memcached出现可以说是革命性次让我们意识到可以用内存作为存储媒介来大规模缓存Cache数据以提高性能不过它毕竟还是比较新东西还需要很多有待优化和改进地方例如:
如何利用memcached实现cache数据库让数据库跑在内存上这方面tangent software 开发memcached_engine[3]已经做了不少工作不过现在版本还只是处于实验室阶段
如何能方便有效进行批量key清理现在key是散列在区别server上所以对某类key进行大批量清理是很麻烦memcached 本身是个大hash表是不具备key检索功能所以memcached是压根不知道某key到底存了多少个都存在哪些server上而这类功能在实际应用中却是经常用到

参考
[1]. Memcached website: http://danga.com/memcached/
[2]. Memcached API Page: http://danga.com/memcached/apis.bml
[3]. memcached_engine: http://tangent.org/506/memcache_engine.html

TAG: 应用 WEB Web 高性能 构建 Memcached


相关文章

读者评论

  • 共0条 分0页

发表评论

  • 昵称:
  • 内容: