項目筆記4-高性能存儲

redis入門

  • Redis是一款基于鍵值對的NoSQL數(shù)據(jù)庫,它的值支持多種數(shù)據(jù)結構:
    字符串(strings)、哈希(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)等。
  • Redis將所有的數(shù)據(jù)都存放在內(nèi)存中,所以它的讀寫性能十分驚人。
    同時,Redis還可以將內(nèi)存中的數(shù)據(jù)以快照或日志的形式保存到硬盤上,以保證數(shù)據(jù)的安全性。
  • Redis典型的應用場景包括:緩存、排行榜、計數(shù)器、社交網(wǎng)絡、消息隊列等。

快照(RDB):優(yōu)點直接把內(nèi)存數(shù)據(jù)原原本本存,恢復數(shù)據(jù)速度塊。缺點是存硬盤耗時,存儲會阻塞,會影響業(yè)務性能。不適合實時去做,適合幾個小時做備份。
日志(aof):每執(zhí)行redis命令,就把命令存下來,追加形式,占磁盤空間,恢復的話,是把命令從頭到尾跑一遍,恢復速度比較慢,實時性好。
https://redis.io
https://github.com/microsoftarchive/redis

redis命令

  1. 內(nèi)置16個庫通過索引區(qū)分,通過下面代碼即可切換庫
select 0
select 15
  1. 刷新庫清空庫的數(shù)據(jù)
flushdb
  1. string類型
set key value
set test:count 1    //兩個單詞相連,中間用冒號,后面可以加超時時間等是可選的
get test:count     //取到字符串
incr test:count     //字符串值加一 increment
decr test:count    //decrement 字符串值減一

4 hash類型

hset key field value
hset test:user id 1 
hset test:user username zhangsan
hget test:user id
hget test:user username

  1. list列表,左右都可以添加和取出
lpush test:ids 101 102 103   //左進
llen test:ids   //得到數(shù)據(jù)長度
lindex test:ids  0   //103  查到索引為0的值,
lrange test:ids 0 2 // 查到從0開始到2 的索引的值
rpop test:ids     //101右側出隊一個值

  1. set集合 無序且唯一
sadd key number
sadd test:teachers aaa bbb ccc ddd eee //集合加入數(shù)據(jù)
scard test:teachers //統(tǒng)計集合元素個數(shù)
spop test:teachers     // 集合中隨機彈出一個元素  ,可以實現(xiàn)抽獎功能
smembers test:teachers //查詢集合中的元素
  1. sortedset 有序集合 按照分數(shù)排序的功能
zadd test:students 10 aaa 20 bbb 30 ccc 40 ddd 50 eee  //數(shù)字代表緊跟后面的成員分數(shù),按照這個分數(shù)給集合從小到大排序
zcard test:students //統(tǒng)計集合元素個數(shù)
zscore test:students ccc // 查詢某個元素的分數(shù)
zrank test:students ccc //2 返回某個元素的排名
zrange test:students 0 2 //取范圍的值,從小到大取三個
  1. 全局命令
keys * //查詢庫里的key
keys test*  //查詢test開頭的key
type test:user //查詢某個key的數(shù)據(jù)類型
exists test:user // 1 表示存在 0 不存在 是否存在key
del test:user // 刪除key
expire test:students 10 //key 10秒過期

Spring整合redis

  • 引入依賴
    spring-boot-starter-data-redis
  • 配置Redis
    配置數(shù)據(jù)庫參數(shù)
    編寫配置類,構造RedisTemplate
  • 訪問Redis
    redisTemplate.opsForValue()
    redisTemplate.opsForHash()
    redisTemplate.opsForList()
    redisTemplate.opsForSet()
    redisTemplate.opsForZSet()
  1. 導入包
  2. 配置參數(shù)


    image.png
  3. 定義RedisConfig
    返回RedisTemplate對象,需要把RedisConnectionFactory注入進來才能創(chuàng)建連接
    調(diào)用(setConnectionFactory())
    spring會把這個參數(shù)自動注入進來,
    然后指定數(shù)據(jù)轉(zhuǎn)換的方式,有工具類RedisSerializer
  • 設置key的序列化方式,序列成string
  • 設置value的序列化方式,可以序列成json
  • 設置hash的key的序列化方式
  • 設置hash的value的序列化方式
    把這些設置生效(調(diào)用afterPropertiesSet())


    image.png
  1. 用法,創(chuàng)建測試實例
    簡化方案,不用每次都傳rediskey參數(shù)
    通過BoundxxxOperations綁定key參數(shù)xxx表示參數(shù)類型。這樣就省略了這個參數(shù)。
    image.png
  2. redis事務
    不完全滿足ACID這四個事務
    開啟事務后,執(zhí)行redis命令會放到隊列里存起來,提交事務的時候,會把這些命令一起批量執(zhí)行。

注意事項:
不要在事務中查詢,這樣是查不到的。要在開啟事務之前或之后查詢
所以因為這個特性,在spring中最好不要用聲明式事務,而是用編程式事務。

public void testTransactional(){
    Object obj = redisTemplate.execute(new SessionCallback(){
    @Override
    public Object execute(RedisOperations operations) throws DataAccessException{
        String redisKey = "test:tx;
        operations.multi(); //開啟事務
        operations.opsForSet().add(redisKey, "zhangsan);
        sout(operations.opsForSet.members(redisKey));    //[] 因為事務中間不要查詢,得不到結果
        return operations.exec(); //關閉事務并返回結果
        }
    });
    sout(obj); // [1, [zhangsan]]  返回的結果是很全的。
}

點贊功能

image.png
  1. 考慮復用,給rediskey復用
    比如點贊,我們需要實現(xiàn)點贊的數(shù)量,但是如果我們擴展功能要找到點贊的人,那麼我們就不要直接存儲點贊的數(shù)量,而是存id這樣就能最大限度擴展功能。


    image.png
  2. LikeService
    點贊方法:要判斷是否點過贊,沒點過才能點,點過就取消
    查詢贊數(shù)量:
    查詢某人對某實體的點贊狀態(tài):返回int而不是boolean是因為未來可能會擴展,比如點個彩。具備擴展性


    image.png

    image.png
  3. LikeController
    用戶權限問題以后會用Spring的安全來管理,所以不用判斷了


    image.png
  4. 異步請求 discuss-detail.html
    把href屏蔽掉,like里面?zhèn)魅齻€參數(shù),this entitytype entityid, this是未了區(qū)分是在哪點的贊,好動態(tài)某一個位置的贊修改。同時要把贊和數(shù)字用標簽進行包裹以便于動態(tài)修改


    image.png

    回帖列表和回復里都有贊

  5. 單獨創(chuàng)建js文件 discuss.js


    image.png
  6. 把首頁和顯示的贊的數(shù)量修改
    顯示的時候贊的狀態(tài)要根用戶相關,因為,這個頁面不登錄也能看到,所以不登錄的話可能匯報空指針異常。

我收到的贊

image.png
  1. 修改我們rediskey


    image.png
  2. LikeService
    點贊重構


    image.png

    統(tǒng)計某個用戶獲得的贊,統(tǒng)計的不是本用戶的id而是傳進來的id


    image.png
  3. 表現(xiàn)層重構
  4. congroller 和discuss-detail三個點贊的參數(shù)傳遞方法
  5. 個人主頁和別人主頁


    image.png

    修改index.html profile路徑,剩下的自己完善

關注和取消關注

  • 需求
    開發(fā)關注、取消關注功能。
    統(tǒng)計用戶的關注數(shù)、粉絲數(shù)。
  • 關鍵
    若A關注了B,則A是B的Follower(粉絲),B是A的Followee(目標)。
    關注的目標可以是用戶、帖子、題目等,在實現(xiàn)時將這些目標抽象為實體。
image.png

image.png

image.png

image.png

在service和controller中補充關注數(shù)量,粉絲數(shù)量,當前用戶是否已經(jīng)關注。并且如果當前用戶不存在,直接返回false;


image.png

image.png

頁面顯示
不可以自己關注自己,而且不登錄不顯示
image.png

顏色顯示


image.png

關注列表和粉絲列表

  • 業(yè)務層
    查詢某個用戶關注的人,支持分頁。
    查詢某個用戶的粉絲,支持分頁。
  • 表現(xiàn)層
    處理“查詢關注的人”、“查詢粉絲”請求。
    編寫“查詢關注的人”、“查詢粉絲”模板。
    關注時間倒序
  1. Followservice
    重點是設計返回數(shù)據(jù)的數(shù)據(jù)結構
    以及時間倒序(最近時間優(yōu)先)的獲得方式。
    List<Map<String, Object>>


    image.png

    粉絲和上面的基本相同。

  2. FollowController


    image.png

    粉絲和上面基本相同

  3. 處理followee和followerhtml頁面

優(yōu)化登錄模塊

  • 使用Redis存儲驗證碼
    驗證碼需要頻繁的訪問與刷新,對性能要求較高。
    驗證碼不需永久保存,通常在很短的時間后就會失效。
    分布式部署時,存在Session共享的問題。
  • 使用Redis存儲登錄憑證
    處理每次請求時,都要查詢用戶的登錄憑證,訪問的頻率非常高。
  • 使用Redis緩存用戶信息
    處理每次請求時,都要根據(jù)憑證查詢用戶信息,訪問的頻率非常高。
驗證碼優(yōu)化
  1. 定義驗證碼key
    因為登錄要標識登錄的用戶是誰,但是此時沒法標識,所以我們用生成的隨機字符串來標識,并把這個字符串通過cookie短暫的保存,
  2. LoginController
    把存入session的驗證碼去掉
    生成隨機字符串,并用cookie保存。并設置生存時間60秒,和路徑。驗證碼存入redis


    image.png

    在登錄具體驗證的時候要用
    判斷cookie是否存在,存在從redis取值,不存在則返回驗證碼不正確

使用redis存儲登錄憑證

不要刪除永久保存,將來出個功能,對于登錄的次數(shù)天數(shù)等需要用到。

  1. 定義ticket的key;
  2. 把LoginTicketMapper定義@Deprecated
  3. UserService
    把LoginTicket對象存進去


    image.png

    修改logout方法


    image.png

    修改findLoginTicket方法
    image.png
緩存用戶信息功能

重構UserService 的findUserById方法
先取緩存,取不到則取mysql的,如果用戶信息改變,有兩種方法,

  • 修改緩存內(nèi)容,
  • 直接刪除緩存。
    第一種麻煩,還會可能遇到并發(fā)的問題。
  1. 步驟
    • 定義key
    • 優(yōu)先從緩存中取值
    • 取不到時初始化緩存數(shù)據(jù)
    • 數(shù)據(jù)變更時刪除緩存

后三個封裝成方法在UserService


image.png
  1. 修改findUserById
    首先從catch查,如果沒有則初始化,
    8.清理緩存的地方
    激活的時候activation把緩存清理
    updateHeader清理緩存,要更新后再清理
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 九、應用級緩存 A.緩存簡介 1.先從緩存中讀取數(shù)據(jù),如果沒有,再從慢速設備上讀取實際數(shù)據(jù)并同步到緩存 2.經(jīng)常讀...
    ZyBlog閱讀 4,609評論 0 14
  • 關系型數(shù)據(jù)庫 關系型數(shù)據(jù)庫依靠著它的ACID特性和強大的SQL語法,目前仍然是各種業(yè)務系統(tǒng)的核心存儲,很多場景下高...
    OldRumble閱讀 1,689評論 1 3
  • 伴解是我們共同的寶藏,我們每個人的一知伴解在這里匯聚。 有些人就會問,怎么玩???我怎么變廢為寶???怎么挖掘?qū)毑匕。?..
    小秋SAKIYA閱讀 251評論 0 0
  • . ——憶我的啟蒙教師吳明老師 記憶中總是忘不了您, 特別是您的那雙手, 教我寫“aoe”一絲不...
    dc13040acc7a閱讀 367評論 2 5
  • 今天我的小寶貝們幼兒園就要畢業(yè)啦。 手機里全部都是你們成長的點點滴滴 愿你們健康成長幸福快樂每一天
    巴拉巴拉鋼琴仙子閱讀 303評論 0 0

友情鏈接更多精彩內(nèi)容