高并发服务器的设计--缓存的设计.doc.docVIP

高并发服务器的设计--缓存的设计.doc.doc

  1. 1、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
高并发服务器的设计--缓存的设计.doc

高并发服务器的设计--缓存的设计 为什么需要缓存呢? 很简单的道理,拿QQ做个比方,每天有几亿用户登录、查询个人信息,且这些信息基本不会变化,如果你是架构师,你会选择全部从数据库中查询么,估计会被笑的。 一些业务要求大量且高速查询的,数据库必然会成为瓶颈,虽然可以通过横向扩容的方式优化,但这不是最优方案,其实服务器优化没有一个放之四海而皆准的最优方案,业务不同,最优方案也不同。 举个例子,腾讯有十几亿用户,就光登录就是个头疼的事,做架构的往往要朝最坏的地方想,比如所有用户同时登录怎么办,难道要像12306那样直接不理你呢? 这样的业务其实并不复杂,却只有一个追求:高速响应,因为用户是用脚投票的。 这些信息都是存放在数据库中的,最终都要和数据库交互,我们用图来显示一次登录的周期: 如果一个用户频繁的登录,注销,服务器是不是总要重复这个周期呢,当然不用,第二,三步取了的数据完全可以放在内存中,周期变成这样: 可以看到当第5步再次请求后,系统已经没有了查询数据库的过程。 这时候缓存就粉末登场了,就是适当的时候要用些内存来代 替硬盘,很简单,内存和硬盘的速度不在一个层次上,只要花些money就可以了。 如何设计缓存呢? 缓存是占内存的,但不是以花尽内存为追求,尼玛,要是哪个架构这么想的,那就是太坑老板了。 相反缓存追求的就是尽量少占内存,这和开头说要占内存不矛盾,因为终极追求是高效,把红管子换成土黄色(请看 “内存池的设计” )。 每一个缓存的方案其实都是一个平衡:快速索引与内存空间,既使你毫不在乎内存的占用,这个平衡还是存在。 缓存方案又分为索引方案、存储方案、排序方案,三者往往是分不开的,在一类业务数据里找出唯一的KEY其实很容易,难的是如何建立索引,如果用标准库自带的map,红黑树方案,这只是解决了存储方案,如果KEY是20个字节,咱顺便也打算用std::string自带的比较函数,好吧,我承认咱找到了一个通用的方案,且这么认为吧。 还是拿QQ为例,QQ号是9位数的数字,如果把这个数字定义成一个int型的,做为数组的基标,把数据全放进这样的数组中,理论上完全可以,那么要多大的内存去存储呢,假设每个用户128字节的信息量,那么就要2^7*2^32=512G,好吧,咱实实在在的坑了回老板。 现实中,不是所有的数据都要放在缓存中,比如有些QQ一年都不登录一下,还有放进缓存的必要么。 对于大量的数据,在需要考虑内存的时候,缓存中应该只存放频繁用到的数据,像女人一样,要保持常鲜才是最美的。 频繁度就是一个阈值,实际就是我们的经验值。 再举一个实际碰到的例子,key是32个字节的,如果用字符串的比较函数,性能上比较憋屈。可以将32字节换成8个int型或者4个long long型,因为CPU可以直接对两个整型进行比较。 实际开发中,我将32字节的key分成了8个int,将所有的缓存数据按模分类分级,先定义中间容器的结构: typedef?struct?yumei_cache_container_s?yumei_cache_container_t;?? struct?yumei_cache_container_s { ????int?????????????????????????container_num;? ????int?????????????????????????data_num;? ????yumei_cache_container_t????*container;? ????void???????????????????????*data; ????int?????????????????????????mm[0];? };? 容器中套有容器,是为了分级散列,对数据的分级散列是很个很不错的方法,可以提高精度,节省时间。再定义索引数据的结构:typedef?struct?yumei_cache_map_data_s?yumei_cache_map_data_t;? struct?yumei_cache_map_data_s? {? ????int?key[8];? ????int?times;? ????int?start_time; ????void*??data;? ????yumei_cache_map_data_t*?next;? }; times是指这个数据被查询过多少次,start_time 则是开始查询时间,这两个参数是为了新陈代谢用的,比如一个数据在昨天天被查了30次,times=30,在昨天会被当 成频繁数据加到缓存里,但是今天一次都没有查过,这样的数据就要被淘汰出去。 定义完了数据结构,就剩下算法了,主要推荐两种: 1.红黑树 2.hash map C里用的红黑树比较多,另一些语言比如JAVA,Phthon用的

文档评论(0)

hhuiws1482 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

版权声明书
用户编号:5024214302000003

1亿VIP精品文档

相关文档