日期:2014-05-20  浏览次数:20437 次

关于千万甚至亿万数量级别的缓存方面研究!高手请进!!!!
假如我有数千万甚至是上亿的用户数据,我想把用户自增ID和用户名UserName放到缓存里。
我的需求是,当要查询用户的信息时,我想先从缓存里根据用户名UserName获取到用户的ID,
然后再通过ID在数据库里查询用户的信息。
我想当一个用户表达到上亿的数量级别时,用自增ID来查询肯定比用UserName来查询快好多倍,即使UserName做了簇级索引。
我现在的疑问是:
1.做这样的缓存需要什么样配置的服务器,ID为自增ID,UserName最大长度为20.上亿数量级的数据,
一个内存为4G的服务器能支持的了吗?
2.应该怎么样来实现缓存,数据几乎不会变化,但是要频繁的新增数据到缓存里,应该怎么样才能既容易写入缓存又容易从缓存里查询数据,并且这些操作不能耗太大的性能。
我能想到的缓存方案有:
  方案1.objCache.Insert(CacheKey, objObject);CacheKey对应的是用户名UserName,objObject对应的是自增ID,通过Cache[UserName]方式来获取自增ID。这样的好处是新增缓存容易,读取缓存数据也很容易。但是问题是,这样新增上亿数量级的缓存性能是否有问题?
  方案2.定义一个Hashtable(哈希表)来存放用户名UserName(key)和自增ID(value),然后把Hashtable存到缓存里,当要查询或者新增数据时把Hashtable从缓存里读取出来,然后再对Hashtable进行查询或者新增数据。但是问题是,这样的Hashtable将是一个非常庞大的对象,频繁的从缓存里写入读取,会不会也很好性能呢?况且上亿数量级别的哈希表Hashtable[key]这样读取数据会快吗?

高手们,你们是怎么处理这个问题的呢?一起来探讨一下吧!

------解决方案--------------------
那个还叫做缓存?

相对于上千亿数据,缓存只是几十个数据为单元的一个一个小集合。

假设一个缓存单元里有100个数据,如果其中只有一个数据的后台对应数据改变了,那么你必须尽快销毁这个缓存单元或者必须确保同步到缓存里,否则所谓缓存就在制造肮脏的数据给业务系统。但是在这种最基本的业务前提下,那种所谓缓存还成立吗?可能是成事不足败事有余的缓存了。
------解决方案--------------------
另外,许多时候我们只需要缓存20分钟,即使这些数据的后台对应数据从来不变化,但是只要前台并不需要读取,为什么要让它们占用内存呢?你知道内存空间比硬盘空间贵多少倍吗?

许多时候我们在数据有20分钟没有被反复读取的时候就必须清除缓存单元,并且缓存系统自己应该有多种内部的机制在物理内存达到一定限度时就将一部分最不频繁使用的数据自动的释放掉,然后释放申请的物理内存空间,直到空出足够多的空间为止。System.Web.Caching.Cache就是这样的可以自动释放缓存数据,并且提供现成的多种CacheDependency同时你也可以自定义CacheDependency的框架。
------解决方案--------------------
探讨
所以我看别人的“缓存系统”设计,仅会分配内存或者写入数据是不是很“可怜”啊,任何人都会的!你有至少一种非常自动化的缓存依赖框架接口功能提供给开发时来调用,这才刚刚可称为应用级的缓存系统啊。

------解决方案--------------------
引子:
海量数据的查询优化是一个很复杂的问题 !

0. 硬件方面;(服务器配置、集群设置、硬盘容量、内存大小等)
1. 从数据库结构;(表结构设计)
2. 从索引;(索引、视图、触发器、游标等)
3. 从SQL语句优化;

所以,你不能单纯的从一两个方面考虑。

正文:
正如你上面所说,那么ID也是放在客户端的缓存中而已,对服务器端不会有什么印象(也算是一种优化吧);至于放在服务器端的缓存那就没必要、也没有那种可能性,很不符合需求。
还有就是4G内存对于一台机子而言,貌似已经很难在扩展了。但是,你又要达到上亿级别的访问,那就不能片面的考了问题了,应该换一种思考方式。可以考虑服务器集群等方面。



------解决方案--------------------
探讨
引用:
引用:
另外,许多时候我们只需要缓存20分钟,即使这些数据的后台对应数据从来不变化,但是只要前台并不需要读取,为什么要让它们占用内存呢?你知道内存空间比硬盘空间贵多少倍吗?

许多时候我们在数据有20分钟没有被反复读取的时候就必须清除缓存单元,并且缓存系统自己应该有多种内部的机制在物理内存达到一定限度时就将一部分最……

------解决方案--------------------
有上亿用户,楼主肯定有钱搞N个服务器啦,别说几条大内存.

当然从技术角度来说,我的建议是:
1. 如果是基于cookie来保存用户名,那可以同时保存ID,查询时直接查询ID

2.如果一定要基于用户名,那就把用户名建索引吧.

3.如果一定要加到缓存中,在加载到缓存中时,只提取近三个月内登录过的用户,估计这样数据量能降低9/10
如果按一个用户占30byte字节,100万用户大约占30M 加上其它支出,50M足够.
4.ASP.NET后台管理cache键/值对时,好象就是基于字典来管理的。读效能没问题,不过,你有这么多要写入的吗?无非就是新注册的用户需要再写入吧?

------解决方案--------------------
探讨
继续期待高手出现,感觉问题还是很模糊,是越来越模糊了

------解决方案--------------------
探讨
另外关于哈希缓存机制,想了解一下这方面的

------解决方案--------------------
我觉得先不要去讨论你的缓存是不是能支持多少数据量,先要看看你用缓存来做什么,如果你是存一个用户的对象,那就要看,这个对象都做什么用,如果只是会用到id,那就存id好了,如果只是用个名字那就存名字好了,而不要一下就把一整个的对象生出来然后一坨坨的放在缓存里,那样做没有丝毫的好处,有很多东西都是在用的时候才去掉,而并不是所有的用户在浏览网站的时候会做所有的事情,你早早的把一个胖对象放在缓存里干什么用呢?即便你有亿万的用户,那你同时在线的人,也不会那么多,我不相信你现在的服务器能支持亿万吞吐量,那你同时在线的人究竟有多少,才是你实际应用时候产生的消耗。

个人拙见,错误之处,大家指正!
------解决方案--------------------
那个还叫做缓存?

相对于上千亿数据,缓存只是几十个数据为单元的一个一个小集合。

假设一个缓存单元里有100个数据,如果其中只有一个数据的后台对应数据改变了,那么你必须尽快销毁这个缓存单元或者必须确保同步到缓存里,否则所谓缓存就在制造肮脏的数据给业务系统。但是在这种最基本的业务前提下,那种所谓缓存还成立吗?可能是成事不足败事有余的缓存了。