Redis+protostuff序列化工具實(shí)現(xiàn)熱點(diǎn)對(duì)象緩存

很多情況我們?yōu)榱私鉀Q并發(fā)問題使用redis非關(guān)系型數(shù)據(jù)庫保存數(shù)據(jù)德崭,我們序列化保存熱點(diǎn)數(shù)據(jù)的傳輸可以隨時(shí)把對(duì)象持久化到數(shù)據(jù)庫、文件等系統(tǒng)里揖盘,也方便我們反序列化獲取對(duì)象眉厨,從而提高用戶體驗(yàn)和系統(tǒng)性能

1.利用maven管理項(xiàng)目,導(dǎo)入相關(guān)jar包


<dependency>

  <groupId>redis.clients</groupId>

  <artifactId>jedis</artifactId>

  <version>2.9.0</version>

</dependency>

<dependency>

  <groupId>com.dyuproject.protostuff</groupId>

  <artifactId>protostuff-core</artifactId>

  <version>1.1.1</version>

</dependency>

<dependency>

  <groupId>com.dyuproject.protostuff</groupId>

  <artifactId>protostuff-runtime</artifactId>

  <version>1.1.1</version>

</dependency>

2.編寫protostuff工具類兽狭,實(shí)現(xiàn)對(duì)象序列化和反序列化


import com.dyuproject.protostuff.LinkedBuffer;

import com.dyuproject.protostuff.ProtostuffIOUtil;

import com.dyuproject.protostuff.Schema;

import com.dyuproject.protostuff.runtime.RuntimeSchema;

import lombok.extern.slf4j.Slf4j;

/**

* protostuff序列化工具

*

* @auth liubing

* @date 2018-03-22

*/

@Slf4j

public class ProtostuffUtil {

    public ProtostuffUtil() {

    }

    /**

    * 對(duì)象序列化

    * @paramo 需要序列化對(duì)象

    * @param 序列化對(duì)象類型

    * @return

    */

    public static byte[] serializer(T o) {

        // 通過對(duì)象的類構(gòu)建對(duì)應(yīng)的schema

        Schema schema= RuntimeSchema.createFrom(o.getClass());

        // 將對(duì)象通過動(dòng)態(tài)生成的schema轉(zhuǎn)換成字節(jié)數(shù)組

        // LinkedBuffer用于緩存較大的對(duì)象

        return ProtostuffIOUtil.toByteArray(o, schema, LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE));

    }

    /**

    * 對(duì)象反序列化

    * @parambytes 對(duì)象字節(jié)數(shù)組

    * @paramclazz Class對(duì)象

    * @param 反序列化對(duì)象

    * @return

    */

    public static T deserializer(byte[] bytes, Class clazz) {

        T obj= null;

        try {

            // 通過對(duì)象的類構(gòu)建對(duì)應(yīng)的schema憾股;

            Schema schema= RuntimeSchema.createFrom(clazz);

            // 通過schema新建一個(gè)對(duì)象,這里需要轉(zhuǎn)換一下

            obj= (T) schema.newMessage();

            // 數(shù)據(jù)反序列化

            ProtostuffIOUtil.mergeFrom(bytes, obj, schema);

        } catch (Exception e) {

            log.error(e.getMessage(),e);

        }

        return obj;

    }

}

3.redis 數(shù)據(jù)庫操作

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Repository;

import redis.clients.jedis.Jedis;

import redis.clients.jedis.JedisSentinelPool;

/**

* 思路:

* 1.查找數(shù)據(jù)時(shí),首先向Redis緩存中查找.

* 2.如果找不到,就轉(zhuǎn)向數(shù)據(jù)庫中查找.

* 2.1將查找到的數(shù)據(jù)放進(jìn)Redis緩存中

* 3.返回查找到的對(duì)象

*

* Created by liubing on 2018/3/21.

*/

@Slf4j

@Repository

public class RedisCacheDao {

    @Autowired

    private JedisSentinelPool jedisSentinelPool;

    /**

    * 從redis中查找數(shù)據(jù)

    * @paramsecKillId

    * @return查詢到的對(duì)象

    */

    public SecKill getSecKill(Long secKillId){

            // 邏輯

            Jedis jedis= jedisSentinelPool.getResource();

            try {

                String key= "secKill_" + secKillId;

                // 從Jedis中獲取序列化的字節(jié)數(shù)組

                byte[] bytes= jedis.get(key.getBytes());

                if (bytes!= null) {

                    // 將字節(jié)數(shù)組再反序列化SecKill

                    SecKill secKill= ProtostuffUtil.deserializer(bytes, SecKill.class);

                    // secKill被反序列化

                    return secKill;

                }

            }finally {

                jedis.close();

            }

        return null;

    }

    /**

    * 將對(duì)象放入redis中

    * @paramsecKill

    * @return如果在鍵中設(shè)置了值則返回OK箕慧。如果值未設(shè)置則返回null

    */

    public String putSecKill(SecKill secKill){

        // 邏輯

        try {

            Jedis jedis= jedisSentinelPool.getResource();

            try {

                String key= "secKill_" + secKill.getSecKillId();

                // 將對(duì)象轉(zhuǎn)換成字節(jié)數(shù)組

                byte[] bytes= ProtostuffUtil.serializer(secKill);

                // 超時(shí)緩存

                // Redis存儲(chǔ)數(shù)據(jù)可以是永久的或是時(shí)限的

                // 對(duì)于數(shù)據(jù)庫緩存來說,一般使用超時(shí)機(jī)制來保證數(shù)據(jù)緩存與數(shù)據(jù)庫數(shù)據(jù)的完整性

                int timeout= 60*60;

                String result= jedis.setex(key.getBytes(),timeout,bytes);

                return  result;

            } finally {

                jedis.close();

            }

        } catch (Exception e){

            log.error(e.getMessage(),e);

        }

        return null;

    }

}

使用哨兵機(jī)制redis服務(wù)服球,配置文件如下:


import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import redis.clients.jedis.HostAndPort;

import redis.clients.jedis.JedisPoolConfig;

import redis.clients.jedis.JedisSentinelPool;

import java.util.HashSet;

import java.util.Set;

/**

* @auth liubing

* @date 2018-03-22

*/

@Configuration

@Slf4j

public class RedisSourceConfig {

    @Value("${redis.maxActive}")

    private String maxActive;

    @Value("${redis.maxIdle}")

    private String maxIdle;

    @Value("${redis.minIdle}")

    private String minIdle;

    @Value("${redis.sentinel.host}")

    private String sentinelHost;

    @Value("${redis.sentinel.port}")

    private String sentinelPort;

    @Value("${redis.cluster.clusterName}")

    private String masterName;

    @Bean

    public JedisPoolConfig jedisPoolConfig(){

        JedisPoolConfig jedisPoolConfig= new JedisPoolConfig();

        jedisPoolConfig.setMaxTotal(Integer.parseInt(maxActive));

        jedisPoolConfig.setMaxIdle(Integer.parseInt(maxIdle));

        jedisPoolConfig.setMinIdle(Integer.parseInt(minIdle));

        jedisPoolConfig.setTestOnBorrow(false);

        jedisPoolConfig.setTestOnReturn(false);

        jedisPoolConfig.setTestWhileIdle(true);

        return jedisPoolConfig;

    }

    @Bean

    public JedisSentinelPool jedisSentinelPool(JedisPoolConfig jedisPoolConfig){

        Set sentinels= new HashSet();

        HostAndPort sentinelHostAndPort= new HostAndPort(sentinelHost, Integer.parseInt(sentinelPort));

        sentinels.add(sentinelHostAndPort.toString());

        JedisSentinelPool jedisSentinelPool= new JedisSentinelPool(masterName, sentinels, jedisPoolConfig);

        return jedisSentinelPool;

    }

}

總結(jié):這個(gè)方法適合存儲(chǔ)對(duì)象,因?yàn)橹攸c(diǎn)是redis保存數(shù)據(jù)時(shí)序列化與獲取數(shù)據(jù)反序列化颠焦。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末斩熊,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子伐庭,更是在濱河造成了極大的恐慌粉渠,老刑警劉巖分冈,帶你破解...
    沈念sama閱讀 216,919評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異霸株,居然都是意外死亡丈秩,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門淳衙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蘑秽,“玉大人,你說我怎么就攤上這事箫攀〕ι” “怎么了?”我有些...
    開封第一講書人閱讀 163,316評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵靴跛,是天一觀的道長缀雳。 經(jīng)常有香客問我,道長梢睛,這世上最難降的妖魔是什么肥印? 我笑而不...
    開封第一講書人閱讀 58,294評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮绝葡,結(jié)果婚禮上深碱,老公的妹妹穿的比我還像新娘。我一直安慰自己藏畅,他們只是感情好敷硅,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評(píng)論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著愉阎,像睡著了一般绞蹦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上榜旦,一...
    開封第一講書人閱讀 51,245評(píng)論 1 299
  • 那天幽七,我揣著相機(jī)與錄音,去河邊找鬼溅呢。 笑死澡屡,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的藕届。 我是一名探鬼主播挪蹭,決...
    沈念sama閱讀 40,120評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼休偶!你這毒婦竟也來了梁厉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,964評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎词顾,沒想到半個(gè)月后八秃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,376評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡肉盹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評(píng)論 2 333
  • 正文 我和宋清朗相戀三年昔驱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片上忍。...
    茶點(diǎn)故事閱讀 39,764評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡骤肛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出窍蓝,到底是詐尸還是另有隱情腋颠,我是刑警寧澤,帶...
    沈念sama閱讀 35,460評(píng)論 5 344
  • 正文 年R本政府宣布吓笙,位于F島的核電站淑玫,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏面睛。R本人自食惡果不足惜絮蒿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望叁鉴。 院中可真熱鬧土涝,春花似錦、人聲如沸亲茅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽克锣。三九已至,卻和暖如春腔长,著一層夾襖步出監(jiān)牢的瞬間袭祟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評(píng)論 1 269
  • 我被黑心中介騙來泰國打工捞附, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留巾乳,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,819評(píng)論 2 370
  • 正文 我出身青樓鸟召,卻偏偏與公主長得像胆绊,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子欧募,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容