讨论:怎么样缓存频繁更新的数据?

      最近接手一个公司的论坛。主题数量大概有100W,回复数有900W,在线人数3000左右。之前设计论坛的GG采用静态集合来缓存每个版块的主题列表。但论坛偶尔会冒出个缓存的bug,其中解决了些问题,但时不时又会有新的bug。ms有点“野火烧不尽春风吹又生”的感觉...
所以我也想着手改善一下,想了想决定重写个原型出来,暂放cnblogs希望大虾们能指点一下迷津。

      我之前的想法是论坛启动时往Memcached服务器填上大量数据,然后Web服务器直接找Cache服务器增、删、改、查 操作。再调个Task跑作业来更新数据库。但因为种种原因再加种种其它原因。所以没有用上Memcached。所以只能凑合利用上Web服务器的内存来改善一下数据库的紧张请求。
现在没有Cache服务器,就用Web服务器的内存吧。目前大体思路是这样:

[1]论坛初始化,获取所有版块ID,循环为每个版块装载一定数量的主题到静态的DictionaryList<T>里 (这个DL集合是我要实现的东西)。
[2]实现一个线程池,线程池定义了一些参数,能定时定量的更新数据库。
[3]当用户发布一个新主题时,将新的主题Id和内容插入到静态 DL集合的顶部,同时删除 DL集合的尾部结点。同时将该主题实体插入线程池。
[4]DL集合需要实现功能如下:
   1、获取分页列表
   2、根据主题ID获取主题实体。(如果静态缓存找不到则从数据库里找)
   3、发布一个新主题时,该主题能插入到DL集合顶端。(论坛贴子都是顶上去的)
   4、 DL集合需要保持一定数量数据,以根据用户操作和实际情况来修改缓存主题数量。
   5、.....未知...

DL集合实现:
测试代码下载连接
using  System;
using  System.Collections.Generic;
using  System.Text;

namespace  Phantaci.Test
{
    
///   <summary>
    
///  原因:
    
///  List集合有根据索引查找的功能,但不支持 key,Value 形式的集合。
    
///  Dictionary支持这种集合,但又不支持索引查找.所以两者关联起来一起用。
    
///  
    
///  需求:
    
///  我需要一个集合类,即能根据集合的索引段来获取实体列表,同时又要根据某个实体ID来获取这个实体。
    
///  当我往集合里"插入、"更新"、"编辑"实体时,当前操作的实体需要置于集合的顶部,同时为了保持实体总数(EntityDictionary.Count),需去除尾部实体。
    
///  
    
///  应用:
    
///  论坛版块列表缓存。当用户进入某版块时,则从DictionaryList获取一个分页列表。当"发表主题"时则把新主题置于DictionaryList顶部。
    
///  同时删除尾部最后一个节,以保持最新的固定的实体数量。主要作用是缓存版块前几十页频繁更新的列表。
    
///   </summary>
    
///   <typeparam name="T"></typeparam>
     public   class  DictionaryList < T >
    {
        
///   <summary>
        
///  用于存放所有实体列表集合类 TopicId,Entity
        
///   </summary>
         private  Dictionary < int , T >  _entityDictionary  =   new  Dictionary < int , T > ();
        
// private Object _objLock = new Object(); 

        
///   <summary>
        
///  索引主题集合类 用于存放TopicId 与 _entityDictionary关联
        
///   </summary>
         private  List < int >  _indexList  =   new  List < int > ();

        
private   int  _pageIndex;
        
private   int  _pageSize;

        
///   <summary>
        
///  当前索引
        
///   </summary>
         public   int  PageIndex
        {
            
get  {  return  _pageIndex; }
            
set  { _pageIndex  =  value; }
        }

        
///   <summary>
        
///  分页大小
        
///   </summary>
         public   int  PageSize
        {
            
get  {  return  _pageSize; }
            
set  { _pageSize  =  value; }
        }

        
///   <summary>
        
///  实体列表
        
///   </summary>
         public  Dictionary < int , T >  EntityDictionary
        {
            
get  {  return  _entityDictionary; }
            
set  { _entityDictionary  =  value; }
        }

        
///   <summary>
        
///  实体总数
        
///   </summary>
         public   int  ItemsCount
        {
            
get  {  return  _entityDictionary.Count; }
        }

        
///   <summary>
        
///  总页数
        
///   </summary>
         public   int  PageCount
        {
            
get  {  return  (ItemsCount  -   1 /  PageSize  +   1 ; }
        }

        
///   <summary>
        
///  默认构造函数
        
///   </summary>
         public  DictionaryList()
        {
            
this ._pageIndex  =   1 ;
            
this ._pageSize  =   20 ;
        }

        
///   <summary>
        
///  有参构造
        
///   </summary>
        
///   <param name="pageSize"></param>
        
///   <param name="entity"></param>
         public  DictionaryList( int  pageSize, Dictionary < int , T >  dict)
        {
            
this ._pageIndex  =   1 ;
            
this ._pageSize  =  pageSize;
            
this ._entityDictionary  =  dict;

            _indexList.Clear();

            
foreach  (KeyValuePair < int , T >  kvp  in  _entityDictionary)
            {
                _indexList.Add(kvp.Key);
            }
        }

        
///   <summary>
        
///  清除集合列表
        
///   </summary>
         public   void  Clear()
        {
            _indexList.Clear();
            _entityDictionary.Clear();
        }

        
///   <summary>
        
///  添加一个实体
        
///  线程不安全???
        
///   </summary>
        
///   <param name="key"></param>
        
///   <param name="entity"></param>
         public   void  AddItems( int  key, T entity)
        {
            
if  ( ! _entityDictionary.ContainsKey(key))
            {
                
// 不存在则往Dictionary添加一个实体(排序问题由List<int>来关联解决)
                _entityDictionary.Add(key, entity);
                
// 关联List<int>
                _indexList.Insert( 0 , key);

                
// 删除列表最底部节点数据
                _indexList.RemoveAt(_indexList.Count  -   1 );
                _entityDictionary.Remove(_indexList[_indexList.Count 
-   1 ]);
            }
            
else
            {
                
// 如果存在,则删除已存在的节点.同时向顶点添加该节点
                _indexList.Remove(key);
                _indexList.Insert(
0 , key);
            }
        }

        
///   <summary>
        
///  获取一个实体
        
///   </summary>
        
///   <param name="key"></param>
        
///   <returns></returns>
         public  T GetItems( int  key)
        {
            
return  _entityDictionary[key];
        }

        
///   <summary>
        
///  是否存当前Key
        
///   </summary>
        
///   <param name="key"></param>
        
///   <returns></returns>
         public   bool  ContainsKey( int  key)
        {
            
return  _entityDictionary.ContainsKey(key);
        }


        
///   <summary>
        
///  分页获取实体列表
        
///   </summary>
        
///   <param name="pageIndex"></param>
        
///   <param name="pageSize"></param>
        
///   <returns></returns>
         public  IList < T >  Pagination( int  pageIndex,  int  pageSize)
        {
            
int  start  =  (pageIndex  -   1 *  pageSize;
            
int  size  =  Math.Min(pageSize, ItemsCount  -  start);

            
if  (start  >  ItemsCount)
                
return   new  List < T > ();

            IList
< T >  list  =   new  List < T > ();

            
for  ( int  i  =   0 ; i  <  size; i ++ )
                list.Add(_entityDictionary[_indexList[start 
+  i]]);

            
return  list;
        }

        
public  IList < T >  Pagination( int  pageIndex)
        {
            
return  Pagination(pageIndex, PageSize);
        }

    }
}






转载于:https://www.cnblogs.com/phantaci/archive/2008/07/04/1235203.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值