Skip to content

【腾讯犀牛鸟开源课题实战】支持LRU Cache #208

Open

Description

@liucf3995
  • 背景:LRU Cache (Least Recently Used,最近最少使用)是业务日常开发中常用的一个 Local Cache 工具,提供 Set/Get 等接口操作 Cache 数据。当缓存容量满了之后,LRU 算法根据数据的历史访问记录顺序来进行数据淘汰,核心思想是”如果数据最近被访问过,那么将来被访问的概率也更高“。业务期望框架能集成一个LRU Cache工具,方便日常开发。
  • 需求:希望你能参考当前已有类库的接口,为tRPC-Cpp设计一套灵活、易用的接口,更好地扩展tRPC的生态。具体来来说,在实现时,你需要注意下面的要点:
    • 增加LUR Cache特性支持,涵盖服务端与客户端,包括协议、编解码、代理等实现与测试。需要支持如下特性:
      • 提供多线程安全的接口。
      • 支持高性能的 Put/Get 操作。
      • 支持LRU淘汰策略。
      • 支持自定义的Key和Value。
      • 支持指定线程Mutex和FiberMutex (框架提供自适应的同步原语)。
    • 你应该尽可能复用tRPC-Cpp的各个模块,具体来说,你应该继承 ServiceProxy,实现一个比如HttpSseProxy,提供设计良好的接口,在实现接口时,应该复用框架的服务发现以及拦截器模块。
  • 参考资料:

小提示:
本issue为2025犀牛鸟开源人才培养活动专属issue,仅供参与犀牛鸟的在校大学生及开发者参与领取,认领前请先报名2025犀牛鸟开源人才培养计划( https://opensource.tencent.com/summer-of-code )。
【认领issue】在issue所在repo页面留言“已成功领取本issue”→微信私信犀牛鸟小助手(活动群-黄贵龙):issue链接+认领截图→犀牛鸟小助手回复“已成功领取本issue”,即可开始做issue任务。
【完成issue】已完成issue的同学,请同步犀牛鸟小助手(私信活动群-黄贵龙回复“已完成本issue任务+代码合入截图等证明”)。
注意:如7天内无提交任何进展包括不限于comment \ commit \ Pull Request,则将视为同学主动放弃issue,组委会将释放issue给下一位等候者。
【第三阶段·实战课题】,需要8月1日入围后即可参与,请勿认领

Activity

  1. ftljk commented on Jul 2, 2025

    @ftljk

    已成功领取本issue

  2. ftljk commented on Jul 10, 2025

    @ftljk

    核心设计架构

    1. CacheServiceProxy设计

    继承ServiceProxy基类,参考HttpServiceProxy的实现模式,设计CacheServiceProxy类:

    class CacheServiceProxy : public ServiceProxy {
    public:
      // 同步Put操作
      template<typename K, typename V>
      Status Put(const ClientContextPtr& context, const K& key, const V& value);
      
      // 异步Put操作  
      template<typename K, typename V>
      Future<Status> AsyncPut(const ClientContextPtr& context, const K& key, const V& value);
      
      // 同步Get操作
      template<typename K, typename V>
      Status Get(const ClientContextPtr& context, const K& key, V* value);
      
      // 异步Get操作
      template<typename K, typename V>
      Future<V> AsyncGet(const ClientContextPtr& context, const K& key);
      
      // 批量操作
      template<typename K, typename V>
      Status BatchPut(const ClientContextPtr& context, const std::vector<std::pair<K, V>>& kvs);
      
      template<typename K, typename V>
      Status BatchGet(const ClientContextPtr& context, const std::vector<K>& keys, std::vector<V>* values);
    };

    2. LRU Cache核心实现

    设计线程安全的LRU Cache实现,支持框架的自适应同步原语:

    template<typename K, typename V, typename MutexType = trpc::fiber::Mutex>
    class LruCache {
    private:
      mutable MutexType mutex_;  // 支持ThreadMutex和FiberMutex
      std::unordered_map<K, typename std::list<std::pair<K, V>>::iterator> cache_map_;
      std::list<std::pair<K, V>> cache_list_;
      size_t capacity_;
      
    public:
      bool Put(const K& key, const V& value);
      bool Get(const K& key, V* value);
      void SetCapacity(size_t capacity);
      size_t Size() const;
      void Clear();
    };

    3. 协议定义

    设计Cache协议,支持Put/Get/Delete/BatchOp等操作:

    // cache.proto
    service CacheService {
      rpc Put(PutRequest) returns (PutResponse);
      rpc Get(GetRequest) returns (GetResponse);
      rpc BatchPut(BatchPutRequest) returns (BatchPutResponse);
      rpc BatchGet(BatchGetRequest) returns (BatchGetResponse);
      rpc Delete(DeleteRequest) returns (DeleteResponse);
    }
    
    message PutRequest {
      bytes key = 1;
      bytes value = 2;
      optional int64 ttl = 3;
    }
    
    message GetRequest {
      bytes key = 1;
    }

    4. 编解码器实现

    实现Cache协议的编解码器,集成到框架的codec系统:

    class CacheClientCodec : public ClientCodec {
    public:
      bool ZeroCopyDecode(const ConnectionPtr& conn, std::deque<std::any>& out) override;
      bool ZeroCopyEncode(const ClientContextPtr& ctx, const ProtocolPtr& in, NoncontiguousBuffer& out) override;
    };
    
    class CacheServerCodec : public ServerCodec {
    public:
      bool ZeroCopyDecode(const ConnectionPtr& conn, std::deque<std::any>& out) override;
      bool ZeroCopyEncode(const ServerContextPtr& ctx, const ProtocolPtr& in, NoncontiguousBuffer& out) override;
    };

    5. 服务端实现

    实现Cache服务端,提供实际的缓存存储功能:

    class CacheServiceImpl : public CacheService {
    private:
      LruCache<std::string, std::string> cache_;
      
    public:
      Status Put(const ServerContextPtr& context, const PutRequest* request, PutResponse* response) override;
      Status Get(const ServerContextPtr& context, const GetRequest* request, GetResponse* response) override;
      Status BatchPut(const ServerContextPtr& context, const BatchPutRequest* request, BatchPutResponse* response) override;
      Status BatchGet(const ServerContextPtr& context, const BatchGetRequest* request, BatchGetResponse* response) override;
    };

    6. 拦截器集成

    复用框架的Filter系统,实现Cache特定的拦截器:

    class CacheMetricsFilter : public ClientFilter {
    public:
      FilterStatus operator()(FilterStatus status, FilterPoint point, const ClientContextPtr& context) override;
    };
    
    class CacheRateLimitFilter : public ClientFilter {
    public:
      FilterStatus operator()(FilterStatus status, FilterPoint point, const ClientContextPtr& context) override;
    };

    7. 服务发现集成

    复用框架的naming系统,支持Cache服务的服务发现:

    // 配置示例
    client:
      service:
        - name: cache_service
          selector_name: direct  # 支持direct、domain等发现方式
          target: 127.0.0.1:8080,127.0.0.1:8081
          protocol: cache
          codec: cache

    8. 自适应同步原语

    支持用户指定同步原语类型,框架自动选择最优实现:

    // 使用FiberMutex
    using FiberLruCache = LruCache<std::string, std::string, trpc::fiber::Mutex>;
    
    // 使用ThreadMutex  
    using ThreadLruCache = LruCache<std::string, std::string, std::mutex>;
    
    // 自适应选择
    template<typename K, typename V>
    using AdaptiveLruCache = LruCache<K, V, trpc::fiber::Mutex>;

    9. 使用示例

    // 客户端使用
    auto proxy = GetProxy<CacheServiceProxy>("cache_service");
    auto context = MakeClientContext(proxy);
    
    // 同步操作
    Status status = proxy->Put<std::string, std::string>(context, "key1", "value1");
    std::string value;
    status = proxy->Get<std::string, std::string>(context, "key1", &value);
    
    // 异步操作
    auto future = proxy->AsyncGet<std::string, std::string>(context, "key1");
    auto result = future.GetValue();
  3. AntiBargu commented on Jul 10, 2025

    @AntiBargu
    Contributor

    已成功领取本issue

  4. xing-cg commented on Jul 10, 2025

    @xing-cg

    已成功领取本issue

  5. daheishandemao commented on Jul 10, 2025

    @daheishandemao

    已成功领取本issue

  6. zhuyanhuazhuyanhua commented on Jul 10, 2025

    @zhuyanhuazhuyanhua

    已成功领取此issue

  7. Rnen-arch commented on Jul 10, 2025

    @Rnen-arch

    已成功领取此issue

  8. NeverGYu commented on Jul 10, 2025

    @NeverGYu

    已成功领取此issue

  9. CrocodilePipo commented on Jul 10, 2025

    @CrocodilePipo

    已成功领取此issue

  10. ResilientSZUer commented on Jul 10, 2025

    @ResilientSZUer

    已成功领取本issue

  11. HappyCR7 commented on Jul 10, 2025

    @HappyCR7

    已成功领取本issue

  12. spiderling2 commented on Jul 11, 2025

    @spiderling2

    已成功领取本issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions