ゼロから手書きredis(四)リスナーの実現


前言
JAvaはゼロから手書きでredisを実現します(一)どのように固定サイズのキャッシュを実現しますか?
JAvaはゼロ手書きからredis(三)redis expireの期限切れ原理を実現する
JAvaはゼロから手書きでredis(3)メモリデータを実現するにはどのように再起動して失わないのですか?
このセクションでは、guava-cacheのようなremoveListener削除リスナーと、redisのスローログモニタリングのようなslowListenerを実現する方法について学習します.
Listenerの削除
説明
2つのシーンでデータを削除することは、ユーザーに対して透過的です.
(1)sizeが満たされた後,データの淘汰を行う.
(2)expireが期限切れになった場合、データを消去します.
この2つの特性はユーザに本来無感であるべきであるが,ユーザが関心を持っていれば削除リスナーを追加することで関連する変更情報を得ることもできる.
実現構想.
削除されたリスニングを実現するには、削除された場所を見つけ、リスナーを呼び出す必要があります.
evict駆除シーン
putデータのたびにsizeが最大の制限に達しているかどうかを検証し、達している場合はevict淘汰を行う.
expire期限切れのシーン
ユーザーがexpire時間を指定した後、バックグラウンドに戻って非同期でリフレッシュを実行します.
削除しないシーンもあります.
インタフェース定義
統合のために、すべての削除を統合インタフェースとして定義します.
/**
 *        
 *
 * @author binbin.hou
 * @since 0.0.6
 * @param  key
 * @param  value
 */
public interface ICacheRemoveListener {

    /**
     *   
     * @param context    
     * @since 0.0.6
     */
    void listen(final ICacheRemoveListenerContext context);

}

組み込み実装
システム内蔵の実装は次のとおりです.
public class CacheRemoveListener implements ICacheRemoveListener {

    private static final Log log = LogFactory.getLog(CacheRemoveListener.class);

    @Override
    public void listen(ICacheRemoveListenerContext context) {
        log.debug("Remove key: {}, value: {}, type: {}",
                context.key(), context.value(), context.type());
    }

}

このリスナーはデフォルトでオンになっており、一時的に閉じることはできません.
ツールバーの
ユーザーは自分のニーズに合わせて、カスタムインプリメンテーションを行うことができます.
public class MyRemoveListener implements ICacheRemoveListener {

    @Override
    public void listen(ICacheRemoveListenerContext context) {
        System.out.println("【    】  ,       !" + context.key());
    }

}

テスト
ICache cache = CacheBs.newInstance()
        .size(1)
        .addRemoveListener(new MyRemoveListener())
        .build();

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

cacheのサイズを1に指定し、カスタム削除リスナーを設定します.
ここの削除リスナーは複数追加できます.
ログ#ログ#
テストログは次のとおりです.
[DEBUG] [2020-09-30 19:32:54.617] [main] [c.g.h.c.c.s.l.r.CacheRemoveListener.listen] - Remove key: 2, value: 2, type: evict
【    】  ,       !2

スローオペレータリスナー
説明
redisには、遅い操作に関するログ情報が格納されます.主に2つのパラメータで構成されています.
(1)slowlog-log-slower-thanプリセットしきい値、その単位はミリ秒(1秒=1000000マイクロ秒)デフォルト値は10000
(2)slowlog-max-len最大何件のスローログ記録を格納するか
ただしredisはメモリに直接格納され、長さに制限があります.
実際の作業体験に基づいて、スロー・ログのリスニングを追加し、対応するストレージまたはアラームを設定すれば、問題の分析と迅速なフィードバックが容易になります.
削除と同様のリスナーを導入しました
実現構想.
すべてのcache操作を処理し,対応する操作を記録するのに時間がかかる.
ユーザが設定した時間しきい値を操作するのに時間がかかる場合は、スローアクションリスナーが呼び出されます.
インタフェース定義
インタフェースの柔軟性を保証するために、各インプリメンテーションは、階層化処理を容易にするために、独自の遅い動作閾値を定義することができる.
例えば100 msを超えると、ユーザはwarnログの出力を選択することができる.1 sを超えると、業務に影響を及ぼす可能性があり、アラームシステムに直接アクセスできます.
public interface ICacheSlowListener {

    /**
     *   
     * @param context    
     * @since 0.0.6
     */
    void listen(final ICacheSlowListenerContext context);

    /**
     *       
     * @return       
     * @since 0.0.9
     */
    long slowerThanMills();

}

カスタムリスナー
実装インタフェース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 cache = CacheBs.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

    実際の作業では、遅いログデータストレージに対して、後期分析を容易にすることができます.
    アラームシステムに直接アクセスし、問題をタイムリーにフィードバックすることもできます.
    小結
    リスナーの実現は比較的簡単であるが,使用者に対する役割は比較的大きい.
    本文では主に構想を述べ、実現部分は紙幅の制限のため、すべて貼られていない.
    オープンソースアドレス:https://github.com/houbb/cache
    本文があなたに役に立つと思ったら、いいねコメントコレクションを歓迎します.
    あなたの励ましは、私の最大の原動力です~