Redisキャッシュ

20863 ワード

Redis
第一歩は、Redisをインストールし、起動後、下記のコードでRedisをテストします.
1.Redis java使用テスト
Redis接続を確立
Jedis jedis = new Jedis("127.0.0.1");
jedis.auth("youxin11");
//  jedis  redis
jedis.set("test123", "my first jedis test");
String string = jedis.get("test123");
System.out.println(string);
//    ,           。       。
jedis.close();
Redis接続池
	JedisPoolConfig poolConfig = new JedisPoolConfig();
	poolConfig.setMaxIdle(redisConfig.getPoolMaxIdle());
	poolConfig.setMaxTotal(redisConfig.getPoolMaxTotal());
	poolConfig.setMaxWaitMillis(redisConfig.getPoolMaxWait() * 1000);
	JedisPool pool = new JedisPool(poolConfig, redisConfig.getHost(), redisConfig.getPort(),
				redisConfig.getTimeout()*1000, redisConfig.getPassword(), 0);
 	
 	Jedis jedis = pool.getResource();
    //  jedis  redis
    jedis.set("test123", "my first jedis test");
    String string = jedis.get("test123");
    System.out.println(string);
    //    ,           。       。
    jedis.close();
    //     。
    pool.close();
2.Redisキャッシュの安全防止
分散プロジェクトでは、redisを導入することによって、アプリケーションの性能と効率を大幅に向上させ、特にデータクエリの面で.しかし、同時にいくつかの問題を持ってきました.最も重要な問題は、データの整合性です.厳密には、この問題は無解です.データの整合性が非常に高いなら、キャッシュは使わないでください.もう一つの典型的な問題はキャッシュスルー、キャッシュ雪崩、キャッシュダウンです.
1.キャッシュクリア
キャッシュが透過しました.データベースが必ず存在しないデータを調べます.通常の使用キャッシュフローは大体、データクエリが先にキャッシュクエリを行い、もしkeyが存在しないか、またはkeyが期限切れになったら、データベースを検索し、照会したオブジェクトをキャッシュに入れる.データベースクエリオブジェクトが空の場合、キャッシュには入れません.ユーザによって開始されたidが「−1」またはidが特に存在しない場合のデータ.この時攻撃者かもしれません.攻撃はデータベースの圧力を大きくします.
ソリューション
1,インターフェース層は検証を追加します.IDに対して基礎検査をします.id<=0の直接ブロックです.2,キャッシュから取れないデータは、データベースからも取り外せません.この時もkey-valueキーをkey-nullと書いてもいいです.キャッシュの有効時間を短く設定してもいいです.60秒(設定が長すぎると正常な状況になります.使えなくなります.)と攻撃ユーザーが同じidで暴力的な攻撃を繰り返すのを防ぐことができます.
	@Reference(version = "1.0.0")
    private GoodsService goodsService;
    
    @Autowired
    private CacheService cacheService;
    
    @RequestMapping(value = "detail", method = RequestMethod.POST)
    public Object detail(HttpServletRequest request) throws Exception{
        String requestStr = RequestStr.geRequestStr(request);
        JSONObject jsonObject = JSONObject.parseObject(RequestStr);
        
        if(StringUtils.isEmpty(jsonObject.getString("goodsId"))){
            throw new DescribeExceeption(ExcetpionEnum.PARAM_ERROR);
        }
        int goodsId = jsonObject.getInteger("goodsId");
        if(goodsId <= 0){
            // id    0 ,         
            throw new DescribeExceeption(ExcetpionEnum.OPERATE_ERROR);
        }
        GoodsInfo goods = (GoodsInfo) cacheService.getCacheByKey("lyn_goods:" + goodsId);
        if(null == goods){
            goods = goodsService.findGoodsInfoByPrimary(goodsId);
            //         ,      ,    ID,   ,    
            if(null != goods){
                cacheService.setCacheToRedis("lyn_goods:" + goodsId, goods, 18000);
            }else{
                cacheService.setCacheToRedis("lyn_goods:" + goodsId, goods, 60);
            }
        }
        return ResultUtils.success(goods);
    }
2.キャッシュ雪崩
キャッシュ雪崩とは、ある時間帯にキャッシュ集中が失効することをいいます.雪崩が発生した原因の一つとしては、すぐに618になり、すぐに一波が買い占められます.これらの買い占め商品は同じ時点(17日23時に入れます)で比較的集中的にキャッシュに入れられています.キャッシュは2時間と仮定します.夜明けの1時になったら、この商品のキャッシュは全部期限が切れます.この時、これらの商品に対する訪問調査はすべてデータベースに落ちました.この時、データベースにとって、大きな圧力をもたらします.
ソリューション:
1,データキャッシュの有効期間を設定すると、時間の後にランダム因子を加算します.
2,キャッシュの有効期限が過ぎたら、ホットタイプのデータをキャッシュする時間が長くなります.
3,ホットスポットのデータを設定しても期限が切れません.
	GoodsInfo goods = goodsService.findGoodsInfoByPrimary(goodsId);
    if(null != goods){
        Random random = new Random();
        //         ,        (    ,        )
        long expire = goods.getIsHotSell() ? 3600 + random.nextInt() * 3600 : 600 + random.nextInt() * 600;
        cacheService.setCacheToRedis("lyn_goods:" + goodsId, goods, expire);
    }
3.キャッシュダウン
キャッシュダウンとは、keyが非常にホットなポイントで、高合併が集中してこの点を訪問することです.このkeyが失効した瞬間、継続的に大合併がキャッシュを突破し、直接にデータベースを要求します.春運期間中に駅のチケット売り場のように、入り口と広場に設置されている自動販売機はチケットの販売ができますが、自動販売機は瞬間的に全部麻痺してしまいます.チケットを大量に買う人がチケット売り場の窓口に殺到しました.
ソリューション:
1,ホットスポットのデータを設定するといつまでも有効期限が切れません.
2、相互反発ロックを加え、相互反発ロックの基準コードは以下の通りである.
GoodsInfo goods = (GoodsInfo) cacheService.getCacheByKey("lyn_goods:" + goodsId);
        if(null != goods){
            String key = "lyn_goods_detail_lock";
            if(cacheService.lock(key, "0")){
                goods = this.getGoodsInfo(goodsId);
                cacheService.unLock(key);
            }else{
                Thread.sleep(100);
                goods = this.getGoodsInfo(goodsId);
            }
        }
4.キャッシュデータの持続化
Redisはデータを定期的にハードディスクに自動的に耐久化する能力を提供しています.RDBとAOFの2つの案を含めて、それぞれ長所とショートボードがあります.データの安定性を確保しながら動作します.
RDB
RDB方式はスナップショット式の耐久化方法であり、ある時点のデータをディスクに耐久化する.そして、起動時に自動的にrdbファイルを読み込み、元のデータを復元します.設定ファイルにRedisを設定してスナップショットを保存することができます.
save [60] [100]
//  Redis 60           ,     100         ,   RDB    。      save  , Redis           。Redis    RDB  。
AOF
AOF耐久方式を採用すると、Redisは各書き込み要求を一つのログファイルに記録します.Redisを再起動すると、AOFファイルに記録されているすべての書き込み手順を一回実行して、データが最新に戻るようにします.AOFはデフォルトでクローズされています.オンにするなら、以下のように構成されています.
appendonly yes
AOFは三つのfsync構成を提供しています.always/eversec/noは、[apendfsync]で指定します.
apendfsync always:ログを書き込むごとに一回fsync操作を行います.データの安全性が一番高いですが、速度が一番遅いです.
apendfsync everrysec:折衷するやり方は、バックグラウンドスレッドが毎秒fsyncで一回渡します.
ブログの元アドレス:
作者:Java開発者記録局のリンク:https://www.jianshu.com/p/ebca78731137 出所:略書の著作権は作者の所有になります.商業転載は作者に連絡して授権を獲得してください.商業転載ではないので、出典を明記してください.