关于千万甚至亿万数量级别的缓存方面研究!高手请进!!!!

txgaozhao 2010-04-21 01:24:40
加精
假如我有数千万甚至是上亿的用户数据,我想把用户自增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]这样读取数据会快吗?

高手们,你们是怎么处理这个问题的呢?一起来探讨一下吧!
...全文
7553 328 打赏 收藏 转发到动态 举报
写回复
用AI写文章
328 条回复
切换为时间正序
请发表友善的回复…
发表回复
guoheng90 2010-05-24
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 matol 的回复:]

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

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

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

正文:
正如你上面所说,那么ID也是放在客户端的缓存中而已,对服务器端不会有什么印象(也算是一种优化吧);至于……
[/Quote]
学习
songfei5201314 2010-05-02
  • 打赏
  • 举报
回复
有管理经验的.NET开发的朋友,加上限500人的QQ群28720769,一起交流。
wcj5689226 2010-05-01
  • 打赏
  • 举报
回复
ASP.NET技术交流群
fly19891011 2010-05-01
  • 打赏
  • 举报
回复
除了觉得跟看天书一样没别的感觉.初学,看这些东西,就像隔着一层厚厚的纱一样!咱要学的太多了。
liji2009 2010-04-30
  • 打赏
  • 举报
回复
期待最佳结果!

高手云集呀
CODE163 2010-04-30
  • 打赏
  • 举报
回复
分表存储解决不了你的问题。只是分表还远远不够。

“在缓存里比较字符串得到ID 然后去数据库检索”LZ是这个意思吗

这个缓存毫无意义。还不如直接到数据库里检索,至少还能节省内存。

硬盘操作是效率的瓶颈 字符串还是数值比较效率上与硬盘操作相比几乎不用考虑,你的这个方案每次都还要去检索数据库一次。还缓存什么呢?我觉得楼主应该把用户的常用信息都缓存,然后把常用用户的信息缓存,放弃不常用的用户,建立良好的缓存过期等管理方案,以便于真正减少对硬盘的读写,虽说有些内存不用浪费,但是也不能用了白用啊。

最少的硬盘读写,最精准的缓存策略,

另外大数量级HASHTABLE等比较“高级”的数据结构就直接不用考虑了。太慢。
dengxiao1981 2010-04-30
  • 打赏
  • 举报
回复
学习了!
为毛呀 2010-04-30
  • 打赏
  • 举报
回复
过来学习一下。
臭脚大仙 2010-04-29
  • 打赏
  • 举报
回复
用户ID存Cookie,数据库根据ID进行分表。
如果同时在线人数不多,可以把用户信息【一行】存入到session中,每次从session取不到时,就从cookie中取ID,到数据库去G根据ID检索,然后再存入session.
如果同时在线人数很多,服务器内存不多,则可以自己写个缓存机制,最多存100个在线用户,插入时,如果达到100,就把最早的那个从HASTABLE(缓存)中移除。
dongzhiyu 2010-04-29
  • 打赏
  • 举报
回复
还是显卡好,用户名和ID存入显存,估计2块2G的显卡够了,CPU得到检索要求后,通过DIRECTX接口通知显卡开始检索,显卡可以并行几百个线程分段检索内容,最后返回检索的ID信息。这样比分表来得更快,而且管理容易。而且CUDA开发难度并不大,估计以楼主的实力还是比较轻松的。
junon 2010-04-29
  • 打赏
  • 举报
回复
我觉得这么大的数据不应该直接缓存数据,而应该缓存如何快速这些数据的方法或者路径——比如缓存索引(无论是自建还是系统默认的)
怫悰 2010-04-29
  • 打赏
  • 举报
回复
[Quote=引用 36 楼 baoxuetianxia 的回复:]
亿万数据 那也忒大了点吧,
干嘛 你要统计中国的贪官数量么?
[/Quote]

这个回的俏皮

没看完,这方面也不熟悉,不过感觉楼主这是要在内存中自己设计一个数据库及软件系统?不要用什么hash表了,数据库软件本身肯定已经优化了。如果数据库的表建立在内存中可以的话,也许可以快点,但是还是让数据库软件来管理吧。对数据库不熟悉,只简单用用,随便猜想的
lihuinihao6315 2010-04-28
  • 打赏
  • 举报
回复
我是来顶 sp1234的,因为他每次说的都有道理。静静期待 缓存系统的形成。
nigerenz 2010-04-28
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 sp1234 的回复:]
那个还叫做缓存?

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

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

赞同,
顺便说一句, 上亿的数据量,用4G的内存配置是不是太寒酸了?哪个公司的?这么抠?呵呵,
LHA 2010-04-28
  • 打赏
  • 举报
回复
晕啊,我说了一大通大实话,居然楼主都没有理我

你的问题:
1.做这样的缓存需要什么样配置的服务器,ID为自增ID,UserName最大长度为20.上亿数量级的数据,
一个内存为4G的服务器能支持的了吗?

-----------
就目前而言,中低档的PC服务器,价格2-3万。完全没有问题,
4G内存的服务器,建议分配给数据的内存为2.5G左右,

一个数据表,如果ID为自增主键,UserName最大长度为20,由于UserName为变长,
1亿条记录占用空间预计为:3.6-4.2G之间,如果对UserName做索引,占用空间X2
也就是7.2-8.5G之间 (当然是个估算值,这与UserName字段存储的内容长度有关)

---------
大家猜猜 一亿条记录的表 检索一条记录速度如何? 10秒? 5秒? 1秒?

如果你服务器配置一般 估计比较慢 要0.X秒,如果配置稍好的应该是0.0X秒

不妨试一试like, 如果使用like '%Key%' 检索 速度将非常慢
如果使用 like 'Key%', 速度会是多少? 呵呵 ,和上面的时间差不多应该在0.X或者0.0

----------

有不少朋友觉得 上千万条记录 上亿条记录 不得了,其实现在的数据库已经能轻松应对这些数据量的数据了
不相信的朋友,可以自己做做实验, 如果手头没有这么多的数据量,可以自己建一个表,
然后写段程序添加数据,一亿条数据添加的时间比较长了,中低档的PC服务器要十几个小时,

对于第二个问题:
2. 你先试一试再考虑是不是要搞什么缓存服务器

--------------

BTW,我幸幸苦苦写了两个回复的帖子,楼主如果真的有心解决问题的话 不妨参考参考
txgaozhao 2010-04-28
  • 打赏
  • 举报
回复
经过这么多高手的讨论,充分吸收了大家的意见方案,决定放弃id放弃缓存的做法
采用表分区,按用户名来分区
下面是我写的一个根据用户名Unicode来计算所在分区的方法(经过测试,这个算法的所得的分区分布基本均匀,测试数据为1千万)
计算出分区后,将分区和用户名一并存入用户表中,数据库就会根据我的分区规则自动将数据存入相应的分区中。查数据也是一样道理,数据库先根据我传入的分区,到所在的分区查找用户信息。
这样查询操作数据的效率将会得到极大的提高了。
谢谢各位高手的指点,我又成长了不少,O(∩_∩)O哈哈~

string UserID = "我是用户名";//用户名长度限制为2-20之间,可以为任意字符,包括中文特殊符号等
Int64 code = 0;//用户名unicode值组合
for (int i = 1; i < UserID.Length; i++)
{
code += (int)UserID[i];//取用户名第一个字符以后的所有字符unicode的值相加
}
code = Int64.Parse(string.Format("{0}{1}", (int)UserID[0], code));//将用户名的第一个字符unicode值与code组合成一个新的数值
Response.Write(code.ToString() + " = " + (code % 100).ToString());//将code模100,所得到的值就是这个用户ID所被划分到的区

nmx253 2010-04-28
  • 打赏
  • 举报
回复
学习一下
辰爸 2010-04-28
  • 打赏
  • 举报
回复
服务器集群把!
liujiayu7344667 2010-04-27
  • 打赏
  • 举报
回复
你还是用本子抄吧 !那么大的数据量你是要模拟原子弹爆炸还是要进行世界人口普查了
cxx8408 2010-04-27
  • 打赏
  • 举报
回复
根据用户名分表,把3个月登录的用户放缓存中,相对会好一点。
加载更多回复(300)

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧