{"id":23630111,"url":"https://github.com/alex-rachel/cache-replacement-policy","last_synced_at":"2025-08-31T05:32:18.066Z","repository":{"id":267212848,"uuid":"624896636","full_name":"Alex-Rachel/Cache-Replacement-Policy","owner":"Alex-Rachel","description":"Cache Replacement Policy","archived":false,"fork":false,"pushed_at":"2023-04-10T09:32:53.000Z","size":1285,"stargazers_count":4,"open_issues_count":0,"forks_count":4,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-01T13:21:15.951Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Alex-Rachel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-04-07T14:29:17.000Z","updated_at":"2024-11-30T00:30:18.000Z","dependencies_parsed_at":"2024-12-09T04:33:03.100Z","dependency_job_id":null,"html_url":"https://github.com/Alex-Rachel/Cache-Replacement-Policy","commit_stats":null,"previous_names":["alex-rachel/cache-replacement-policy"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Alex-Rachel/Cache-Replacement-Policy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alex-Rachel%2FCache-Replacement-Policy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alex-Rachel%2FCache-Replacement-Policy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alex-Rachel%2FCache-Replacement-Policy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alex-Rachel%2FCache-Replacement-Policy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Alex-Rachel","download_url":"https://codeload.github.com/Alex-Rachel/Cache-Replacement-Policy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alex-Rachel%2FCache-Replacement-Policy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272940761,"owners_count":25018971,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-31T02:00:09.071Z","response_time":79,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-28T01:33:31.226Z","updated_at":"2025-08-31T05:32:17.456Z","avatar_url":"https://github.com/Alex-Rachel.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Cache-Replacement-Policy\n## 缓存替换策略 C#实现（Cache Replacement Policy）\n[![DotNet](https://img.shields.io/badge/DotNet-5.0++-blue.svg?style=flat-square)](https://github.com/ALEXTANGXIAO/Cache-Replacement-Policy)\n[![License](https://img.shields.io/github/license/ALEXTANGXIAO/Cache-Replacement-Policy)](https://github.com/ALEXTANGXIAO/Cache-Replacement-Policy)\n[![License](https://img.shields.io/github/last-commit/ALEXTANGXIAO/Cache-Replacement-Policy)](https://github.com/ALEXTANGXIAO/Cache-Replacement-Policy)\n[![License](https://img.shields.io/github/issues/ALEXTANGXIAO/Cache-Replacement-Policy)](https://github.com/ALEXTANGXIAO/Cache-Replacement-Policy)\n---\n常用缓存替换策略及C#实现\n\n- \u003cstrong\u003e1.LFU：(Least Frequently Used)最近最不常用算法,根据数据的历史访问频率来淘汰数据\u003c/strong\u003e\n\n    核心思想是：最近使用频率高的数据很大概率将会再次被使用,而最近使用频率低的数据,很大概率不会再使用。\n\n    做法：把使用频率最小的数据置换出去。这种算法是完全从使用频率的角度去考虑的。\n\n    ### 执行过程理解:\n\n    ![Image text](./img/LFU.png)\n\n    1.在缓存中查找客户端需要访问的数据\n\n    2.如果缓存命中，则将访问的数据从队列中取出，并将数据对应的频率计数加1，然后将其放到频率相同的数据队列的头部，比如原来是A(10)-\u003eB(9)-\u003eC(9)-\u003eD(8),D被访问后，它的time变成了9，这时它被提到A和B之间，而不是继续在C后面\n\n    3.如果没有命中，表示缓存穿透，将需要访问的数据从磁盘中取出，加入到缓存队列的尾部，记频率为1，这里也是加入到同为1的那一级的最前面\n    \n    4.如果此时缓存满了，则需要先置换出去一个数据，淘汰队列尾部频率最小的数据，然后再在队列尾部加入新数据。\n\n    \u003cstrong\u003e存在的问题：\u003c/strong\u003e\n\n    某些数据短时间内被重复引用，并且在很长一段时间内不再被访问。由于它的访问频率计数急剧增加，即使它在相当长的一段时间内不会被再次使用，也不会在短时间内被淘汰。这使得其他可能更频繁使用的块更容易被清除，此外，刚进入缓存的新项可能很快就会再次被删除，因为它们的计数器较低，即使之后可能会频繁使用。\n\n- \u003cstrong\u003e2.LRU（Least Recently User） 最近最少使用算法,根据数据的历史访问记录来进行淘汰数据\u003c/strong\u003e\n\n    核心思想是：最近使用的数据很大概率将会再次被使用。而最近一段时间都没有使用的数据，很大概率不会再使用。\n\n    做法：把最长时间未被访问的数据置换出去。这种算法是完全从最近使用的时间角度去考虑的。\n\n    ### 执行过程理解:\n\n    ![Image text](./img/LRU.png)\n\n    1.在缓存中查找客户端需要访问的数据 如果缓存命中，则将访问的数据中队列中取出，重新加入到缓存队列的头部。\n\n    2.如果没有命中，表示缓存穿透，将需要访问的数据从磁盘中取出，加入到缓存队列的尾部；\n\n    3.如果此时缓存满了，淘汰队列尾部的数据，然后再在队列头部加入新数据。\n\n    \u003cstrong\u003e存在的问题：\u003c/strong\u003e\n\n    缓存污染：如果某个客户端访问大量历史数据时，可能使缓存中的数据被这些历史数据替换，其他客户端访问数据的命中率大大降低。\n\n- \u003cstrong\u003e3.Adaptive Replacement Cache(ARC) 自适应缓存替换算法,它结合了LRU与LFU,来获得可用缓存的最佳使用。\u003c/strong\u003e\n\n    ![Image text](./img/ARC_Info1.png)\n    ![Image text](./img/ARC_Info2.png)\n\n    核心思想是：当时访问的数据趋向于访问最近的内容，会更多地命中LRU list，这样会增大LRU的空间； 当系统趋向于访问最频繁的内容，会更多地命中LFU list，这样会增加LFU的空间.\n\n    执行过程理解:\n    \n    1. 整个Cache分成两部分，起始LRU和LFU各占一半，后续会动态适应调整partion的位置（记为p）除此，LRU和LFU各自有一个ghost list(因此，一共4个list)\n    ![Image text](./img/ARC1.png)\n    2. 在缓存中查找客户端需要访问的数据， 如果没有命中，表示缓存穿透，将需要访问的数据 从磁盘中取出，放到LRU链表的头部。\n    ![Image text](./img/ARC2.png)\n    3. 如果命中，且LFU链表中没有，则将数据放入LFU链表的头部，所有LRU链表中的数据都必须至少被访问两次才会进入LFU链表。如果命中，且LFU链表中存在，则将数据重新放到LFU链表的头部。这么做，那些真正被频繁访问的页面将永远呆在缓存中，不经常访问的页面会向链表尾部移动，最终被淘汰出去。\n    ![Image text](./img/ARC3.png)\n    4. 如果此时缓存满了，则从LRU链表中淘汰链表尾部的数据，将数据的key放入LRU链表对应的ghost list。然后再在链表头部加入新数据。如果ghost list中的元素满了，先按照先进先出的方式来淘汰ghost list中的一个元素，然后再加入新的元素。\n    ![Image text](./img/ARC4.png)\n    这里注意上面的the cache才是实际的LRU和LFU结合的链表，因此是删除了LRU链表的尾部元素，尾部元素对应下面的位置索引是1。\n    ![Image text](./img/ARC6.png)\n    5. 如果没有命中的数据key处于ghost list中，则表示是一次幽灵（phantom）命中，系统知道，这是一个刚刚淘汰的页面，而不是第一次读取或者说很久之前读取的一个页面。ARC用这个信息来调整它自己，以适应当前的I/O模式（workload）。\n    \n    这个迹象说明我们的LRU缓存太小了。在这种情况下，LRU链表的长度将会被增加1，并将命中的数据key从ghost list中移除，放入LRU链表的头部。显然，LFU链表的长度将会被减少1。\n    \n    同样，如果一次命中发生在LFU ghost 链表中，它会将LRU链表的长度减一，以此在LFU 链表中加一个可用空间。\n    ![Image text](./img/ARC7.png)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falex-rachel%2Fcache-replacement-policy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falex-rachel%2Fcache-replacement-policy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falex-rachel%2Fcache-replacement-policy/lists"}