• Stars
    star
    360
  • Rank 118,230 (Top 3 %)
  • Language
    Shell
  • License
    Other
  • Created over 4 years ago
  • Updated 6 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

The basic cache tool for java.(java 手写实现渐进式 redis 缓存工具)

项目简介

Cache 用于实现一个可拓展的本地缓存。

有人的地方,就有江湖。

有高性能的地方,就有 cache。

Maven Central Build Status Open Source Love

创作目的

  • 为日常开发提供一套简单易用的缓存框架

  • 便于后期多级缓存开发

  • 学以致用,开发一个类似于 redis 的渐进式缓存框架

特性

  • MVP 开发策略

  • fluent 流式编程体验,纵享丝滑

  • 支持 cache 固定大小

  • 支持自定义 map 实现策略

  • 支持 expire 过期特性

  • 支持自定义 evict 驱除策略

内置 FIFO 和 LRU 驱除策略

  • 支持自定义删除监听器

  • 日志整合框架,自适应常见日志

  • 支持 load 初始化和 persist 持久化

RDB 和 AOF 两种模式

变更日志

变更日志

快速开始

准备

JDK1.7 及其以上版本

Maven 3.X 及其以上版本

maven 项目依赖

<dependency>
    <groupId>com.github.houbb</groupId>
    <artifactId>cache-core</artifactId>
    <version>0.0.15</version>
</dependency>

入门测试

ICache<String, String> cache = CacheBs.<String,String>newInstance()
                .size(2)
                .build();

cache.put("1", "1");
cache.put("2", "2");
cache.put("3", "3");
cache.put("4", "4");

Assert.assertEquals(2, cache.size());

默认为先进先出的策略,此时输出 keys,内容如下:

[3, 4]

引导类配置属性

CacheBs 作为缓存的引导类,支持 fluent 写法,编程更加优雅便捷。

上述配置等价于:

ICache<String, String> cache = CacheBs.<String,String>newInstance()
                .map(Maps.<String,String>hashMap())
                .evict(CacheEvicts.<String, String>fifo())
                .size(2)
                .build();

淘汰策略

目前内置了几种淘汰策略,可以直接通过 CacheEvicts 工具类创建。

策略 说明
none 没有任何淘汰策略
fifo 先进先出(默认策略)
lru 最基本的朴素 LRU 策略,性能一般
lruDoubleListMap 基于双向链表+MAP 实现的朴素 LRU,性能优于 lru
lruLinkedHashMap 基于 LinkedHashMap 实现的朴素 LRU,与 lruDoubleListMap 差不多
lru2Q 基于 LRU 2Q 的改进版 LRU 实现,命中率优于朴素LRU
lru2 基于 LRU-2 的改进版 LRU 实现,命中率优于 lru2Q

过期支持

ICache<String, String> cache = CacheBs.<String,String>newInstance()
        .size(3)
        .build();

cache.put("1", "1");
cache.put("2", "2");

cache.expire("1", 10);
Assert.assertEquals(2, cache.size());

TimeUnit.MILLISECONDS.sleep(50);
Assert.assertEquals(1, cache.size());
System.out.println(cache.keySet());

cache.expire("1", 10); 指定对应的 key 在 10ms 后过期。

删除监听器

说明

淘汰和过期,这些都是缓存的内部行为。

如果用户也关心的话,可以自定义删除监听器。

自定义监听器

直接实现 ICacheRemoveListener 接口即可。

public class MyRemoveListener<K,V> implements ICacheRemoveListener<K,V> {

    @Override
    public void listen(ICacheRemoveListenerContext<K, V> context) {
        System.out.println("【删除提示】可恶,我竟然被删除了!" + context.key());
    }

}

使用

ICache<String, String> cache = CacheBs.<String,String>newInstance()
        .size(1)
        .addRemoveListener(new MyRemoveListener<String, String>())
        .build();

cache.put("1", "1");
cache.put("2", "2");
  • 测试日志
【删除提示】可恶,我竟然被删除了!2

添加慢操作监听器

说明

redis 中会存储慢操作的相关日志信息,主要是由两个参数构成:

(1)slowlog-log-slower-than 预设阈值,它的单位是毫秒(1秒=1000000微秒)默认值是10000

(2)slowlog-max-len 最多存储多少条的慢日志记录

不过 redis 是直接存储到内存中,而且有长度限制。

根据实际工作体验,如果我们可以添加慢日志的监听,然后有对应的存储或者报警,这样更加方便问题的分析和快速反馈。

所以我们引入类似于删除的监听器。

自定义监听器

实现接口 ICacheSlowListener

这里每一个监听器都可以指定自己的慢日志阈值,便于分级处理。

public class MySlowListener implements ICacheSlowListener {

    @Override
    public void listen(ICacheSlowListenerContext context) {
        System.out.println("【慢日志】name: " + context.methodName());
    }

    @Override
    public long slowerThanMills() {
        return 0;
    }

}

使用

ICache<String, String> cache = CacheBs.<String,String>newInstance()
        .addSlowListener(new MySlowListener())
        .build();

cache.put("1", "2");
cache.get("1");
  • 测试效果
[DEBUG] [2020-09-30 17:40:11.547] [main] [c.g.h.c.c.s.i.c.CacheInterceptorCost.before] - Cost start, method: put
[DEBUG] [2020-09-30 17:40:11.551] [main] [c.g.h.c.c.s.i.c.CacheInterceptorCost.after] - Cost end, method: put, cost: 10ms
【慢日志】name: put
[DEBUG] [2020-09-30 17:40:11.554] [main] [c.g.h.c.c.s.i.c.CacheInterceptorCost.before] - Cost start, method: get
[DEBUG] [2020-09-30 17:40:11.554] [main] [c.g.h.c.c.s.i.c.CacheInterceptorCost.after] - Cost end, method: get, cost: 1ms
【慢日志】name: get

实际工作中,我们可以针对慢日志数据存储,便于后期分析。

也可以直接接入报警系统,及时反馈问题。

添加 load 加载器

说明

有时候我们需要在 cache 初始化的时候,添加对应的数据初始化。

后期可以从文件等地方加载数据。

实现

实现 ICacheLoad 接口即可。

public class MyCacheLoad implements ICacheLoad<String,String> {

    @Override
    public void load(ICache<String, String> cache) {
        cache.put("1", "1");
        cache.put("2", "2");
    }

}

我们在缓存初始化的时候,放入 2 个元素。

测试效果

ICache<String, String> cache = CacheBs.<String,String>newInstance()
        .load(new MyCacheLoad())
        .build();

Assert.assertEquals(2, cache.size());

添加 persist 持久化类

说明

如果我们只是把文件放在内存中,应用重启信息就丢失了。

有时候我们希望这些 key/value 信息可以持久化,存储到文件或者 database 中。

持久化

CachePersists.<String, String>dbJson("1.rdb") 指定将数据文件持久化到文件中。

定期执行,暂时全量持久化的间隔为 10min,后期考虑支持更多配置。

public void persistTest() throws InterruptedException {
    ICache<String, String> cache = CacheBs.<String,String>newInstance()
            .load(new MyCacheLoad())
            .persist(CachePersists.<String, String>dbJson("1.rdb"))
            .build();

    Assert.assertEquals(2, cache.size());
    TimeUnit.SECONDS.sleep(5);
}
  • 1.rdb

文件内容如下:

{"key":"2","value":"2"}
{"key":"1","value":"1"}

加载器

存储之后,可以使用对应的加载器读取文件内容:

ICache<String, String> cache = CacheBs.<String,String>newInstance()
        .load(CacheLoads.<String, String>dbJson("1.rdb"))
        .build();

Assert.assertEquals(2, cache.size());

后期 Road-MAP

淘汰策略

  • CLOCK 算法

  • SC 二次机会

  • 老化算法

  • 弱引用

过期特性

  • 过期策略添加随机返回

  • expireAfterWrite()

  • expireAfterAccess()

持久化

  • AOF 混合 RDB

统计

  • 命中率

  • keys 数量

  • evict 数量

  • expire 数量

  • 耗时统计

并发

  • 并发安全保障

其他

  • 异步 callable 操作

  • spring 整合

提供 @Cacheable 系列注解

  • 文件压缩

  • 独立服务端

提供类似于 redis-server + redis-client 的拆分,便于独立于应用作为服务存在。

拓展阅读

java从零手写实现redis(一)如何实现固定大小的缓存?

java从零手写实现redis(三)redis expire 过期原理

java从零手写实现redis(三)内存数据如何重启不丢失?

java从零手写实现redis(四)添加监听器

java从零手写实现redis(五)过期策略的另一种实现思路

java从零手写实现redis(六)AOF 持久化原理详解及实现

java从零开始手写redis(七)LRU 缓存淘汰策略详解

java从零开始手写redis(八)朴素 LRU 淘汰算法性能优化

java 从零开始手写 redis(九)LRU 缓存淘汰算法如何避免缓存污染

java 从零开始手写 redis(十)缓存淘汰算法 LFU 最少使用频次

java 从零开始手写 redis(11)clock时钟淘汰算法详解及实现

java 从零开始手写 redis(12)redis expire 过期如何实现随机获取keys?

java从零开始手写 redis(13)HashMap 源码原理详解

java 从零开始手写 redis(14)redis渐进式rehash详解

java 从零开始手写 redis(15)实现自己的 HashMap

java 从零开始手写 redis(16)实现渐进式 rehash map

【实战汇总】

缓存实战(1)缓存雪崩、缓存击穿和缓存穿透入门简介及解决方案

缓存实战(2)布隆过滤器是啥?guava 的 BloomFilter 使用

缓存实战(3)让你彻底搞懂布隆过滤器!实现一个自己的BloomFilter

缓存实战(4)bloom filter 使用最佳实践,让你少踩坑

java 从零实现属于你的 redis 分布式锁

3天时间,我是如何解决redis bigkey删除问题的?

redis 多路复用

中间件等工具开源矩阵

heaven: 收集开发中常用的工具类

rpc: 基于 netty4 实现的远程调用工具

mq: 简易版 mq 实现

ioc: 模拟简易版 spring ioc

mybatis: 简易版 mybatis

cache: 渐进式 redis 缓存

jdbc-pool: 数据库连接池实现

sandglass: 任务调度时间工具框架

sisyphus: 支持注解的重试框架

resubmit: 防止重复提交框架,支持注解

auto-log: 日志自动输出

async: 多线程异步并行框架

缓存相关工具

cache: 手写渐进式 redis

common-cache: 通用缓存标准定义

redis-config: 兼容各种常见的 redis 配置模式

lock: 开箱即用的分布式锁

resubmit: 防重复提交

rate-limit: 限流

More Repositories

1

sensitive-word

👮‍♂️The sensitive word tool for java.(敏感词/违禁词/违法词/脏词。基于 DFA 算法实现的高性能 java 敏感词过滤工具框架。请勿发布涉及政治、广告、营销、翻墙、违反国家法律法规等内容。高性能敏感词检测过滤组件,附带繁体简体互换,支持全角半角互换,汉字转拼音,模糊搜索等功能。)
Java
4,032
star
2

sensitive

🔐Sensitive log tool for java, based on java annotation. (基于注解的 java 日志脱敏工具框架,更加优雅的日志打印。支持自定义哈希、支持基于 log4j2 插件的统一脱敏、支持 logback 插件统一脱敏)
Java
566
star
3

opencc4j

🇨🇳Open Chinese Convert is an opensource project for conversion between Traditional Chinese and Simplified Chinese.(java 中文繁简体转换)
Java
465
star
4

awesome-metaverse-zh

Awesome metaverse projects (元宇宙精选资源汇总)
Batchfile
348
star
5

pinyin

The high performance pinyin tool for java.(java 高性能中文转拼音工具。支持同音字。)
Java
230
star
6

word-checker

🇨🇳🇬🇧Chinese and English word spelling corrector.(中文易错别字检测,中文拼写检测纠正。英文单词拼写校验工具)
Java
229
star
7

nlp-hanzi-similar

The hanzi similar tool.(汉字相似度计算工具,中文形近字算法。可用于手写汉字识别纠正,文本混淆等。)
Java
215
star
8

junitperf

⛵️Junit performance rely on junit5 and jdk8+.(java 性能测试框架。性能测试。压测。测试报告生成。)
Java
184
star
9

sisyphus

The java retry framework.(支持注解的 java 重试框架)
Java
181
star
10

markdown-toc

🎄Generate toc for github markdown file.(为 markdown 文件生成 toc 目录)
Java
167
star
11

segment

The jieba-analysis tool for java.(基于结巴分词词库实现的更加灵活优雅易用,高性能的 java 分词实现。支持词性标注。)
Java
137
star
12

mq

The message queue in java.(java 简易版本 mq 实现)
Java
113
star
13

rpc

Java rpc framework based on netty4.(java 手写 dubbo rpc 框架)
Java
97
star
14

data-factory

🏭Auto generate mock data for java test.(便于 Java 测试自动生成对象信息)
Java
87
star
15

resubmit

The repeat submit tool for java.(java 防止重复提交框架,支持注解。支持 spring, springboot 整合。)
Java
78
star
16

iexcel

📚IExcel is a java tool for create and read excel easy.(excel 读取和写入,解决 excel OOM 问题。)
Java
53
star
17

idoc

🌾Generate doc for java maven project.(java 项目自动生成文档)
Java
50
star
18

auto-log

The auto log tool for java.(java 自动日志输出,基于字节码,兼容 spring)
Java
48
star
19

validator

🚥Fluent-validation framework for java extend from hibernate-validator.(java 对象属性流式验证框架,下一代校验框架。兼容实现 jakarta bean validation、jsr 303、hibernate-validator)
Java
45
star
20

lombok-ex

Java compile time annotation, lombok extension framework.(java 编译时注解框架,对 lombok 进行扩展)
Java
43
star
21

heaven

⭐Collect basic useful tools for java dev.(收集开发中常用的工具类)
Java
37
star
22

ioc

The java ioc framework(从零开始手写模拟 spring Ioc 框架)
Java
34
star
23

word-cloud

The word cloud tool for java.(java 好用的词云工具-云图)
Java
31
star
24

nginx4j

nginx4j 是 nginx 的java 版本。
Java
31
star
25

async

🦄The async tool for java.(Java 多线程异步并行框架,基于 java 字节码,支持注解。)
Java
28
star
26

houbb.github.io

🧀The blog for github pages.
JavaScript
28
star
27

mybatis

The simple mybatis.(手写简易版 mybatis)
Java
23
star
28

csv

The csv read/write tool based on java annotation.(基于 java 注解的 CSV 文件读写框架工具。)
Java
23
star
29

rate-limit

🎃Rate limit for java.(java 渐进式限流工具框架,支持 spring springboot 字节码)
Java
22
star
30

sensitive-word-admin

The sensitive tool admin.(敏感词工具对应的控台)
HTML
20
star
31

minicat

The mini tomcat.(手写从零实现简易版 tomcat。别称【嗅虎】心有猛虎,轻嗅蔷薇。)
Java
18
star
32

jdbc-pool

The jdbc pool for java.(java 手写 jdbc 数据库连接池实现)
Java
17
star
33

lock

The distributed lock tool for java.(java 实现开箱即用基于 redis 的分布式锁,支持可重入锁获取。内置整合 spring、springboot。)
Java
8
star
34

leetcode

The leetcode problem solutions.(力扣算法个人学习笔记) 查询、排序、五大算法汇总
Java
3
star
35

houbb

my readme
1
star
36

nlp-keyword

nlp-keyword based on segment.(基于分词的 NLP keyword 关键词)
Java
1
star
37

hibernate

The simple database orm hibernate.(java 从零实现简易版本 hibernate)
Java
1
star
38

mvc

High performance web mvc framework for java.(高性能 java web mvc 框架)
Java
1
star
39

logstash4j

log stash in java.(简易版 logstash 实现)
Java
1
star