6. 主要功能序列图
1.1 设置缓存数据的序列图
流程说明:
1. 前端应用发起数据Set请求
2. NetIO模块读取请求包,并判断请求包是否已经读取完整
3. 请求包读取完整,NetIO模块通过Workpooll,选择一个Worker处理线程,将请求包放入线程对应的缓存队列,并唤醒Woker处理线程进行处理。
4. Worker处理线程判断当前Set数据是否有效,并判断Key是否已经存在Index记录,且版本信息高于当前请求值,若是,需拒绝当前Set请求。否则,从目前有效的memcached中,随机选择一个作为存储入口。(根据memcached容量信息来随机选择,大容量memcached具有大的当选概率)
5. 淘汰策略:如果当前选择中memcached的已使用内存容量接近最大值,那么从索引map中找到最老结点,淘汰之。这样作可以比较好的处理索引和内存容量之间的供需矛盾。
6. Woker将Index更新信息保存在Jgroups通知缓存队列中,待Jgroups-msg-snder发送更新消息,通知到索引集群内其他索引服务器。
7. Worker处理线程根据获取到的memcached入口信息,获取到此memcached的长连接,保存应用应用数据。若保存失败,需删除相应Index信息。
8. Worker处理线程拼装Set响应信息,通过NetIO.RespDispatcher找到对应的前端应用连接入口,将响应包缓存到响应缓存队列。
9. NetIO模块将响应包发送至应用前端。
1.2 读取缓存数据的序列图
流程说明:
1. 前端应用发起数据Get请求
2. NetIO模块读取请求包,并判断请求包是否已经读取完整
3. 请求包读取完整,NetIO模块通过WokerPool,选择一个Worker处理线程,将请求包放入线程对应的缓存队列,并唤醒Woker处理线程进行处理。
4. Worker处理线程首先判断Key是否在本地索引表中存在记录,若无则直接通知前端应用 Get失败。另外,需判断索引是否已经超时,或对应的后端memcached是否当前有效。
5. Worker处理线程根据获取到的memcached入口信息,获取到此memcached的长连接,查询应用应用数据。若查询失败,需删除相应Index信息。
6. Worker处理线程拼装Get响应信息,通过Netio.RespDispatcher找到对应的前端应用连接入口,将响应包缓存到响应缓存队列。
7. NetIO模块将响应包发送至应用前端。
7. 性能统计
目前分布式cache系统已经应用在拍拍商城,为商品中图提供cache服务。商品中图平均大小为13.6k,从运营统计中获取相关性能数据如下:
• 峰值处理能力达到,每分钟 111531 次(每秒钟 1858)请求其中 99.8% 的请求在 10 毫秒钟以内完成,并且CPU的利用率在 20% 以下;
• 目前使用的cached共计48G,共40个memcached进程,缓存图片索引 3517242,命中率稳定在 85%至90%之间。
预计峰值处理能力可以达到 5000次/秒。
8. 优化经验
• 使用java nio实现实现网络接入,事件驱动处理业务;
• 使用suse64位操作系统获得系统线程以及大内存的支援;
• 使用jprofile进行服务的性能优化;
• 使用share nothing 的理念设计索引结构,尽可能减小同步以及加锁操作。
9. 总结
实践证明以为索引服务为中心的分布式cache系统具有很高的可用性、扩展性以及较好的性能,而且可以充分利用在线运营服务器上的空闲内存。后续分布式cache系统将会在商城应用到商品详情、店铺详情等业务上,以期发布更大的作用。
文章TAG: