zoukankan      html  css  js  c++  java
  • 高并发之config

    对于config的读取,再熟悉不过了,通常的写法如下:

    //1. read from cache
    string configvalue = GetFromCache(configKey);
    if(!configValue.IsNullOrEmpty()){
        return configValue;
    }
    
    //2. read from db
    configValue = GetFromDb(configKey);
    if(configValue.IsNullOrEmpty()){
        // set to cache 30s
        retrun config;
    }

    这种写法在普通的场景下,完全是可行的 先从cache中读,再从db中读取,设置30s缓存时间

    但当遇到高并发的场景下: 即如果瞬时有10000个或更多的请求,来读取这个config,恰巧碰到,30s过期的临界值。此时全部的请求压力就会转向db,缓存就会miss。

    这里有个概念:

    滑动过期 :即config 从本地内存中读取,同时开启一个定时器,定时从cache中同步config到本地内存中

    public class ConfigFacade
        {
            private const int FRESHEN_INTERVAL = 30 * 1000;
            private static readonly ConcurrentDictionary<string, string> localCache = new ConcurrentDictionary<string, string>();
            private static Timer _timer;
            static ConfigFacade()
            {
                Console.WriteLine("timer start ...");
                _timer = new Timer(state => LoadConfig(), null, FRESHEN_INTERVAL, FRESHEN_INTERVAL);
            }
    
            private static void LoadConfig()
            {
                //sync configvalue to localcache
                foreach (var key in localCache.Keys)
                {
                    var configValue = GetConfigFromClient(key);
                    var tryUpdateValue = localCache.TryUpdate(key, configValue, localCache[key]);
                    Console.WriteLine("now : {0}", DateTime.Now);
                    Console.WriteLine("update key :{0} , {1}", key, tryUpdateValue);
                }
            }
    
            public static string GetConfig(string key)
            {
                string value;
                if (localCache != null && localCache.Count > 0 && localCache.ContainsKey(key))
                {
                    var tryGetValue = localCache.TryGetValue(key, out value);
                    if (tryGetValue)
                    {
                        return value;
                    }
                }
    
                value = GetConfigFromClient(key);
                localCache.TryAdd(key, value);
                return value;
            }
    
            private static string GetConfigFromClient(string key)
            {
                // 1. from redis 
                // 2. from db 
                Console.WriteLine("key => {0} ,get value form client", key);
                return string.Format("{0}_value", key);
            }
        }

    优点

    1. 每次并发的读取都能保证是读取本地内存,定时器会定时的去同步缓存到本地内存
    2. 这种处理问题的思路 类似于将config 放到一个池子里,永远保证这个池子里有值
    六度与心 修行苦 苦修行
  • 相关阅读:
    c++ 设计模式6 (Decorator 装饰模式)
    c++ 设计模式7 (Bridge 桥模式)
    c++ 设计模式8 (Factory Method 工厂方法)
    c++ 设计模式9 (Abstract Factory 抽象工厂模式)
    C++类设计2(Class with pointer members)
    C++类设计1(Class without pointer members)
    算法总结—链表
    C++对象内存模型1(堆栈模型)
    PHP 页面编码声明方法详解(header或meta)
    php变量与数组相互转换的方法(extract与compact
  • 原文地址:https://www.cnblogs.com/hdtechnology/p/8732671.html
Copyright © 2011-2022 走看看