场景
我有以下方法:
public void AddItemSecurity(int itemId, int[] userIds)
public int[] GetValidItemIds(int userId)一开始,我在考虑表格上的存储:
itemId -> userId, userId, userId和
userId -> itemId, itemId, itemIdAddItemSecurity是基于如何从第三方API获取数据的,GetValidItemIds是我希望在运行时使用它的方式。
可能有2000名用户和1 000万件物品。id项在表单上: 2007123456,2010001234 (前四位代表年份)。
AddItemSecurity不需要执行超快,但是GetValidIds需要次秒级。另外,如果对现有的itemId进行了更新,我需要为不再在列表中的用户删除该itemId。
我正在考虑如何以一种最佳的方式储存这个。最好在磁盘上(带缓存),但我希望代码可维护和干净。
如果项id从0开始,我考虑为每个用户创建一个长度为MaxItemId / 8的字节数组,并在项目是否存在时设置一个true/false位。这将使每个用户的数组长度限制在略大于1mb,并提供快速查找以及更新每个用户列表的简单方法。通过在内存映射文件 4框架中将其作为.Net保持下来,我想我也会得到很好的缓存(如果机器有足够的内存),而无需自己实现缓存逻辑。解析id、去掉年份并每年存储一个数组可能是一个解决方案。
可以将ItemId -> UserId[]列表直接序列化到磁盘,并使用普通的FileStream进行读写,以便持久化列表并在发生更改时对其进行区分。
每次添加新用户时,所有的列表都必须更新,但这可以在夜间完成。
问题
我应该继续尝试这个方法,还是应该探索其他的途径?我认为SQL server的执行速度不够快,并且会产生开销(至少如果它是托管在另一个服务器上的话),但是我的假设可能是错误的。任何关于这件事的想法或见解都会受到赞赏。我想在不增加太多硬件的情况下解决这个问题:)
更新2010-03-31
我现在已经在以下条件下使用SQL server 2008进行了测试。
如果我运行一个线程,它的平均值为0.2秒。当我添加第二个线程时,它上升到0.4秒,这仍然是可以的。从那时起,结果越来越少。添加第三个线程会给查询带来最多2秒的时间。第四个线程最多可达4秒,第五个线程将一些查询提高到50秒。
CPU正在屋顶运行,甚至在一个线程上也是如此。我的测试应用程序采用了一些由于快速循环,其余的sql。
这使我得出结论,它不会很好地扩展。至少在我测试过的硬件上没有。是否有优化数据库的方法,例如,为每个用户存储一个int数组,而不是每项存储一个记录。但这使得移除物品变得更加困难。
更新2010-03-31 #2
我对相同的数据进行了快速测试,将其作为位放在内存映射文件中。表现要好得多。六个线程产生在0.02s到0.06s之间的访问时间。纯粹的记忆束缚。映射的文件由一个进程映射,另有6个进程同时访问。由于sql基的容量为4gb,磁盘上的文件占用23 as。
发布于 2010-06-15 06:45:55
经过多次测试,我最终使用内存映射文件,使用来自使用C#的NTFS稀疏文件的代码用稀疏位(NTFS)标记它们。
维基百科解释了稀疏文件是什么。
使用稀疏文件的好处是,我不必关心我的id在哪个范围内。如果我只在2006000000到2010999999之间写入id,该文件将只从文件中的偏移量250,750,000分配625,000字节。直到该偏移量的所有空间都在文件系统中未分配。每个id都作为一个设置位存储在文件中。有点像位数组。如果id序列突然改变,那么它将在文件的另一部分中分配。
为了检索设置了哪个id,我可以执行一个OS调用来获取稀疏文件的分配部分,然后检查这些序列中的每个位。此外,检查是否设置了特定的id是非常快的。如果它不在分配的块之外,那么它就不存在了,如果它在其中,它只是一个字节读取和一个位掩码检查,以确定是否设置了正确的位。
因此,对于有很多id的特定场景,您希望以尽可能快的速度检查它,这是我迄今为止找到的最理想的方法。
更好的是,内存映射的文件也可以与Java共享(这最终是必需的)。Java还支持Windows上的内存映射文件,实现读/写逻辑非常简单。
发布于 2010-03-30 14:16:15
我真的认为在你做出决定之前,你应该尝试一个很好的数据库。从长远来看,这样的事情将是一个挑战。你的用户群实际上很小。Server应该能够在没有任何问题的情况下处理所需的内容。
发布于 2010-03-30 14:28:18
2000用户并不是很糟糕,但是有了10百万相关的项目,您确实应该考虑将其放入数据库中。DBs完成了您需要的所有存储、持久化、索引、缓存等,它们的性能非常好。
它们还允许将来具有更好的可伸缩性。如果您突然需要处理200万用户和数十亿设置,有一个良好的数据库到位将使缩放不成问题。
https://stackoverflow.com/questions/2545882
复制相似问题