Redis入門

Redis

  • 概念: redis是一款高性能的NOSQL系列的非關(guān)系型數(shù)據(jù)庫
    • 什么是NOSQL

NoSQL(NoSQL = Not Only SQL)愉适,意即“不僅僅是SQL”,是一項(xiàng)全新的數(shù)據(jù)庫理念严蓖,泛指非關(guān)系型的數(shù)據(jù)庫。
隨著互聯(lián)網(wǎng)web2.0網(wǎng)站的興起,傳統(tǒng)的關(guān)系數(shù)據(jù)庫在應(yīng)付web2.0網(wǎng)站雷激,特別是超大規(guī)模和高并發(fā)的SNS類型的web2.0純動(dòng)態(tài)網(wǎng)站已經(jīng)顯得力不從心访圃,暴露了很多難以克服的問題厨幻,而非關(guān)系型的數(shù)據(jù)庫則由于其本身的特點(diǎn)得到了非常迅速的發(fā)展。NoSQL數(shù)據(jù)庫的產(chǎn)生就是為了解決大規(guī)模數(shù)據(jù)集合多重?cái)?shù)據(jù)種類帶來的挑戰(zhàn)腿时,尤其是大數(shù)據(jù)應(yīng)用難題况脆。

  • NOSQL和關(guān)系型數(shù)據(jù)庫比較

  1. 優(yōu)點(diǎn):
  • 成本:nosql數(shù)據(jù)庫簡單易部署,基本都是開源軟件批糟,不需要像使用oracle那樣花費(fèi)大量成本購買使用格了,相比關(guān)系型數(shù)據(jù)庫價(jià)格便宜。
  • 查詢速度:nosql數(shù)據(jù)庫將數(shù)據(jù)存儲(chǔ)于緩存之中徽鼎,關(guān)系型數(shù)據(jù)庫將數(shù)據(jù)存儲(chǔ)在硬盤中盛末,自然查詢速度遠(yuǎn)不及nosql數(shù)據(jù)庫。
  • 存儲(chǔ)數(shù)據(jù)的格式:nosql的存儲(chǔ)格式是key,value形式纬傲、文檔形式满败、圖片形式等等,所以可以存儲(chǔ)基礎(chǔ)類型以及對象或者是集合等各種格式叹括,而數(shù)據(jù)庫則只支持基礎(chǔ)類型算墨。
  • 擴(kuò)展性:關(guān)系型數(shù)據(jù)庫有類似join這樣的多表查詢機(jī)制的限制導(dǎo)致擴(kuò)展很艱難。
  1. 缺點(diǎn):
  • 維護(hù)的工具和資料有限汁雷,因?yàn)閚osql是屬于新的技術(shù)净嘀,不能和關(guān)系型數(shù)據(jù)庫10幾年的技術(shù)同日而語。
  • 不提供對sql的支持侠讯,如果不支持sql這樣的工業(yè)標(biāo)準(zhǔn)挖藏,將產(chǎn)生一定用戶的學(xué)習(xí)和使用成本。
  • 不提供關(guān)系型數(shù)據(jù)庫對事務(wù)的處理厢漩。

  • 非關(guān)系型數(shù)據(jù)庫的優(yōu)勢:
  1. 性能NOSQL是基于鍵值對的膜眠,可以想象成表中的主鍵和值的對應(yīng)關(guān)系,而且不需要經(jīng)過SQL層的解析溜嗜,所以性能非常高宵膨。
  2. 可擴(kuò)展性同樣也是因?yàn)榛阪I值對,數(shù)據(jù)之間沒有耦合性炸宵,所以非常容易水平擴(kuò)展辟躏。
  • 關(guān)系型數(shù)據(jù)庫的優(yōu)勢:
  1. 復(fù)雜查詢可以用SQL語句方便的在一個(gè)表以及多個(gè)表之間做非常復(fù)雜的數(shù)據(jù)查詢。
  2. 事務(wù)支持使得對于安全性能很高的數(shù)據(jù)訪問要求得以實(shí)現(xiàn)土全。對于這兩類數(shù)據(jù)庫捎琐,對方的優(yōu)勢就是自己的弱勢会涎,反之亦然。

總結(jié):
關(guān)系型數(shù)據(jù)庫與NoSQL數(shù)據(jù)庫并非對立而是互補(bǔ)的關(guān)系瑞凑,即通常情況下使用關(guān)系型數(shù)據(jù)庫末秃,在適合使用NoSQL的時(shí)候使用NoSQL數(shù)據(jù)庫,讓NoSQL數(shù)據(jù)庫對關(guān)系型數(shù)據(jù)庫的不足進(jìn)行彌補(bǔ)拨黔。一般會(huì)將數(shù)據(jù)存儲(chǔ)在關(guān)系型數(shù)據(jù)庫中蛔溃,在nosql數(shù)據(jù)庫中備份存儲(chǔ)關(guān)系型數(shù)據(jù)庫的數(shù)據(jù)

  • 主流的NOSQL產(chǎn)品

redis、memcached篱蝇、mongodb贺待、guava(loadingCache)


  1. 鍵值(Key-Value)存儲(chǔ)數(shù)據(jù)庫
  • 相關(guān)產(chǎn)品: Tokyo Cabinet/Tyrant、Redis零截、Voldemort麸塞、Berkeley DB
  • 典型應(yīng)用: 內(nèi)容緩存,主要用于處理大量數(shù)據(jù)的高訪問負(fù)載涧衙。
  • 數(shù)據(jù)模型: 一系列鍵值對
  • 優(yōu)勢: 快速查詢
  • 劣勢: 存儲(chǔ)的數(shù)據(jù)缺少結(jié)構(gòu)化
  1. 列存儲(chǔ)數(shù)據(jù)庫
  • 相關(guān)產(chǎn)品:Cassandra, HBase, Riak
  • 典型應(yīng)用:分布式的文件系統(tǒng)
  • 數(shù)據(jù)模型:以列簇式存儲(chǔ)哪工,將同一列數(shù)據(jù)存在一起
  • 優(yōu)勢:查找速度快,可擴(kuò)展性強(qiáng)弧哎,更容易進(jìn)行分布式擴(kuò)展
  • 劣勢:功能相對局限
  1. 文檔型數(shù)據(jù)庫
  • 相關(guān)產(chǎn)品:CouchDB雁比、MongoDB
  • 典型應(yīng)用:Web應(yīng)用(與Key-Value類似,Value是結(jié)構(gòu)化的)
  • 數(shù)據(jù)模型: 一系列鍵值對
  • 優(yōu)勢:數(shù)據(jù)結(jié)構(gòu)要求不嚴(yán)格
  • 劣勢: 查詢性能不高撤嫩,而且缺乏統(tǒng)一的查詢語法
  1. 圖形(Graph)數(shù)據(jù)庫
  • 相關(guān)數(shù)據(jù)庫:Neo4J偎捎、InfoGrid、Infinite Graph
  • 典型應(yīng)用:社交網(wǎng)絡(luò)
  • 數(shù)據(jù)模型:圖結(jié)構(gòu)
  • 優(yōu)勢:利用圖結(jié)構(gòu)相關(guān)算法序攘。
  • 劣勢:需要對整個(gè)圖做計(jì)算才能得出結(jié)果茴她,不容易做分布式的集群方案。

redis和memcached各有什么優(yōu)勢

  • 內(nèi)存管理機(jī)制
    • Memcached默認(rèn)使用Slab Allocation機(jī)制管理內(nèi)存程奠,其主要思想是按照預(yù)先規(guī)定的大小丈牢,將分配的內(nèi)存分割成特定長度的塊 以存儲(chǔ)相應(yīng)長度的key-value數(shù)據(jù)記錄,以完全解決內(nèi)存碎片問題瞄沙〖号妫空閑列表進(jìn)行判斷存儲(chǔ)狀態(tài)
    • Redis使用現(xiàn)場申請內(nèi)存的方式來存儲(chǔ)數(shù)據(jù),并且很少使用free-list(空閑列表)等方式來優(yōu)化內(nèi)存分配距境,會(huì)在一定程度上存在內(nèi)存碎片【CPU內(nèi)存是連續(xù)泛粹,類似于Java虛擬機(jī)對象的分配,直接內(nèi)存分配(指針碰撞)】
memcached空閑分配.jpg
memcache數(shù)據(jù)存儲(chǔ).jpg

如上肮疗,memcached預(yù)先定義很多內(nèi)存大小的空間,并記錄扒接,然后根據(jù)存儲(chǔ)數(shù)據(jù)的大小來選擇那種大小的空間伪货,而redis則是直接存儲(chǔ)们衙,即使120一段,實(shí)際存儲(chǔ)的數(shù)據(jù)只占用20碱呼,那么就浪費(fèi)了100的內(nèi)存蒙挑。

redis數(shù)據(jù)存儲(chǔ).png
  • 數(shù)據(jù)持久化方案

    • memcached不支持內(nèi)存數(shù)據(jù)的持久化操作,所有的數(shù)據(jù)都以in-memory的形式存儲(chǔ)愚臀。
    • redis支持持久化操作忆蚀。redis提供了兩種不同的持久化方法來講數(shù)據(jù)存儲(chǔ)到硬盤里面,
      • 第一種是rdb形式姑裂,一種是aof形式
        • rdb:屬于全量數(shù)據(jù)備份馋袜,備份的是數(shù)據(jù)
        • aof:append only if,增量持久化備份,備份的是指令[如:set key舶斧, del key]
  • 緩存數(shù)據(jù)過期機(jī)制

    • Memcached 在刪除失效主鍵時(shí)也是采用的消極方法欣鳖,即 Memcached 內(nèi)部也不會(huì)監(jiān)視主鍵是否失效,而是在通過 Get 訪問主鍵時(shí)才會(huì)檢查其是否已經(jīng)失效
    • Redis 定時(shí)茴厉、定期等多種緩存失效機(jī)制泽台,減少內(nèi)存泄漏
  • 支持的數(shù)據(jù)類型

    • Memcached支持單一數(shù)據(jù)類型,[k,v]
    • redis支持五種數(shù)據(jù)類型

什么是Redis

Redis是用C語言開發(fā)的一個(gè)開源的高性能鍵值對(key-value)數(shù)據(jù)庫,官方提供測試數(shù)據(jù)矾缓,50個(gè)并發(fā)執(zhí)行100000個(gè)請求,讀的速度是110000次/s,寫的速度是81000次/s 怀酷,且Redis通過提供多種鍵值數(shù)據(jù)類型來適應(yīng)不同場景下的存儲(chǔ)需求,目前為止Redis支持的鍵值數(shù)據(jù)類型如下:


  1. 字符串類型 string
  2. 哈希類型 hash
  3. 列表類型 list
  4. 集合類型 set
  5. 有序集合類型 sortedset

redis的應(yīng)用場景


  • 緩存(數(shù)據(jù)查詢嗜闻、短連接蜕依、新聞內(nèi)容、商品內(nèi)容等等)
    • 作為mybatis/hibernate二級(jí)緩存(mapper緩存)使用方案泞辐,當(dāng)然其默認(rèn)也有一級(jí)方案笔横,只不過是內(nèi)存緩存
    • 解釋下一級(jí)緩存:sqlSession緩存,進(jìn)程緩存咐吼,單次鏈接有效吹缔;當(dāng)使用了clearCache方法和,或者close方法的話锯茄,這個(gè)緩存失效厢塘,如果還有同樣的查詢,則還會(huì)發(fā)送一次查詢
  • 聊天室的在線好友列表
  • 任務(wù)隊(duì)列肌幽。(秒殺晚碾、搶購、12306等等)
  • 應(yīng)用排行榜
  • 網(wǎng)站訪問統(tǒng)計(jì)
  • 數(shù)據(jù)過期處理(可以精確到毫秒
  • 分布式集群架構(gòu)中的session分離

redis作為數(shù)據(jù)庫的使用有什么優(yōu)缺點(diǎn)

  • 優(yōu)點(diǎn):沒有Scheme約束喂急,數(shù)據(jù)結(jié)構(gòu)的變更相對容易格嘁,一開始確定數(shù)據(jù)類型,抗壓能力強(qiáng)廊移,性能極高糕簿,10萬/qps
  • 缺點(diǎn):沒有索引探入,沒有外鍵,缺少int/date等基本數(shù)據(jù)類型懂诗,多條件查詢需要通過集合內(nèi)聯(lián)(sinter,zinterstore) 和連接間接實(shí)現(xiàn)開發(fā)效率低蜂嗽,可維護(hù)性不佳

下載安裝方式一


  1. 官網(wǎng):https://redis.io
  2. 中文網(wǎng):http://www.redis.net.cn/
  3. 解壓直接可以使用:
    • redis.windows.conf:配置文件
    • redis-cli.exe:redis的客戶端
    • redis-server.exe:redis服務(wù)器端

下載安裝方式二

  • 解決could not retrieve mirrorlist,

    • sudo vim /etc/sysconfig/network-scripts/ifcfg-ens33
    • 將ONBOOT改為yes殃恒,wq!保存退出
    • 重新啟動(dòng)網(wǎng)絡(luò)
    $ service network restart
    
  • 安裝wget : yum -y install wget

  • 下載redis安裝包

wget http://download.redis.io/releases/redis-4.0.6.tar.gz

  • 解壓壓縮包

tar -zxvf redis-4.0.6.tar.gz

  • yum install gcc
  • 跳轉(zhuǎn)到redis解壓目錄下 cd redis-4.0.6
  • 編譯安裝
    • make MALLOC=libc
    • cd src && make install
  • 測試是否安裝成功
    cd src ./redis-server

redis三種啟動(dòng)方式以及其中的使用區(qū)別

  • 直接啟動(dòng)

cd src ./redis-server

  • 通過指定配置文件啟動(dòng)
    • 首先修改redis.conf文件(在根目錄下)的daemonize no為yes
    • 可以輸入/然后輸入dae按下enter這樣就可以搜索到然后保存
    • 進(jìn)入redis的目錄下的src目錄植旧,然后執(zhí)行以下,就是守護(hù)進(jìn)程啟動(dòng)
./redis-server  /usr/local/redis-4.0.6/redis.conf

可以通過下面方式測試是否啟動(dòng)成功 : ./redis-cli -p 6379

  • 補(bǔ)充
    • 針對守護(hù)進(jìn)程啟動(dòng)的方式關(guān)閉進(jìn)程:
    • 查詢進(jìn)程信息 ps -ef|grep redis
    • 關(guān)閉進(jìn)程: kill -9 8370

8370是進(jìn)程號(hào)离唐,而且會(huì)有倆進(jìn)程病附,找到server那個(gè)即可,一般第一個(gè)

  • 使用redis啟動(dòng)腳本設(shè)置開機(jī)自啟動(dòng)
    • linux配置開啟自啟動(dòng)腳本都在這個(gè)文件夾下面 /etc/init.d,系統(tǒng)啟動(dòng)的時(shí)候會(huì)自動(dòng)執(zhí)行該文件夾下面的腳本侯繁,所以把redis啟動(dòng)腳本移動(dòng)進(jìn)來即可
    • 啟動(dòng)腳本 redis_init_script 位于Redis的 /utils/ 目錄下 (redis提供的)
    • mkdir /etc/redis
    • cp redis.conf /etc/redis/6379.conf
    • 將啟動(dòng)腳本復(fù)制到/etc/init.d目錄下胖喳,本例將啟動(dòng)腳本命名為redisd(通常都以d結(jié)尾表示是后臺(tái)自啟動(dòng)服務(wù))
    • cp redis_init_script /etc/init.d/redisd
    • 設(shè)置為開機(jī)自啟動(dòng),直接配置開啟自啟動(dòng) chkconfig redisd on 發(fā)現(xiàn)錯(cuò)誤: service redisd does not support chkconfig
    • 解決辦法贮竟,在啟動(dòng)腳本開頭添加如下注釋來修改運(yùn)行級(jí)別(修改腳本修改的是:/etc/init.d/redisd)
     #!/bin/sh
     # chkconfig:   2345 90 10
    
    • 設(shè)置開機(jī)自啟:chkconfig redisd on
    • 驗(yàn)證是否啟動(dòng): service redisd start,如果提示已啟動(dòng)則可證明設(shè)置開機(jī)自啟成功了

打開服務(wù): service redisd start #關(guān)閉服務(wù) : service redisd stop

命令操作


  1. 選擇數(shù)據(jù)庫

redis默認(rèn)有16個(gè)數(shù)據(jù)庫丽焊,不選擇的話寫入默認(rèn)是0數(shù)據(jù)庫,但是可以手動(dòng)指定

select 0

  1. redis的數(shù)據(jù)結(jié)構(gòu):
  • redis存儲(chǔ)的是:key,value格式的數(shù)據(jù)咕别,其中key都是字符串技健,value有5種不同的數(shù)據(jù)結(jié)構(gòu)
  • value的數(shù)據(jù)結(jié)構(gòu):
    • 字符串類型 string
    • 哈希類型 hash : map格式
    • 列表類型 list : linkedlist格式。支持重復(fù)元素
    • 集合類型 set : 不允許重復(fù)元素
    • 有序集合類型 sortedset:不允許重復(fù)元素惰拱,且元素有順序
  1. 字符串類型 string
    1. 存儲(chǔ): set key value
      127.0.0.1:6379> set username zhangsan
      OK
    2. 獲却萍: get key
      127.0.0.1:6379> get username
      "zhangsan"
    3. 刪除: del key
      127.0.0.1:6379> del age
      (integer) 1
    4. mget:批量獲取多個(gè)key的值,如果可以不存在則返回nil
    5. incr && incrby :incr對key對應(yīng)的值進(jìn)行加加操作偿短,并返回新的值;incrby加指定值
    6. decr && decrby:decr對key對應(yīng)的值進(jìn)行減減操作欣孤,并返回新的值;decrby減指定值
    7. setnx:設(shè)置key對應(yīng)的值為String類型的value澄耍,如果key已經(jīng)存在則返回0
    8. setex:設(shè)置key對應(yīng)的值為String類型的value颖医,并設(shè)定有效期
    9. 其他命令
      • getrange: 獲取key對應(yīng)value的子字符串
      • mset: 批量設(shè)置多個(gè)key的值,如果成功表示所有值都被設(shè)置钠署,否則返回0表示沒有任何值被設(shè)置
      • msetnx: 同mset勾怒,不存在就設(shè)置婆排,不會(huì)覆蓋已有的key
      • getset: 設(shè)置key的值,并返回key舊的值
      • append: 給指定key的value追加字符串笔链,并返回新字符串的長度
  2. 哈希類型 hash
  • Hash是一個(gè)String類型的field和value之間的映射表段只,
  • redis的Hash數(shù)據(jù)類型的key(hash表名稱)對應(yīng)的value實(shí)際的內(nèi)部存儲(chǔ)結(jié)構(gòu)為一個(gè)HashMap
  • Hash特別適合存儲(chǔ)對象。
  • 相對于把一個(gè)對象的每個(gè)屬性存儲(chǔ)為String類型鉴扫,將整個(gè)對象存儲(chǔ)在Hash類型中會(huì)占用更少內(nèi)存赞枕。
  • 所存儲(chǔ)的成員較少時(shí)數(shù)據(jù)存儲(chǔ)為zipmap,當(dāng)成員數(shù)量增大時(shí)會(huì)自動(dòng)轉(zhuǎn)成真正的HashMap,此時(shí)encoding為ht。
  • 運(yùn)用場景:如用一個(gè)對象來存儲(chǔ)用戶信息鹦赎,商品信息谍椅,訂單信息等等。
    1. 存儲(chǔ): hset key field value

      • 127.0.0.1:6379> hset myhash username lisi
        (integer) 1
      • 127.0.0.1:6379> hset myhash password 123
        (integer) 1
    2. 獲裙呕啊:

      • hget key field: 獲取指定的field對應(yīng)的值
        127.0.0.1:6379> hget myhash username
        "lisi"
      • hgetall key:獲取所有的field和value
        127.0.0.1:6379> hgetall myhash
        • "username"
        • "lisi"
        • "password"
        • "123"
    3. 刪除: hdel key field
      127.0.0.1:6379> hdel myhash username
      (integer) 1

    4. hlen--返回key對應(yīng)的HashMap中的field的數(shù)量

  1. 列表類型 list:可以添加一個(gè)元素到列表的頭部(左邊)或者尾部(右邊)
    1. 添加:
      1. lpush key value: 將元素加入列表左表

      2. rpush key value:將元素加入列表右邊

             127.0.0.1:6379> lpush myList a
             (integer) 1
             127.0.0.1:6379> lpush myList b
             (integer) 2
             127.0.0.1:6379> rpush myList c
             (integer) 3
        
    2. 獲取:
      • lrange key start end :范圍獲取
        127.0.0.1:6379> lrange myList 0 -1
        • "b"
        • "a"
        • "c"
    3. 刪除:
      • lpop key: 刪除列表最左邊的元素锁施,并將元素返回
      • rpop key: 刪除列表最右邊的元素陪踩,并將元素返回
  1. 集合類型 set : 不允許重復(fù)元素

    1. 存儲(chǔ):sadd key value
      • 127.0.0.1:6379> sadd myset a
        (integer) 1
      • 127.0.0.1:6379> sadd myset a
        (integer) 0
    2. 獲取:smembers key:獲取set集合中所有元素
      • 127.0.0.1:6379> smembers myset
        1) "a"
    3. 刪除:srem key value:刪除set集合中的某個(gè)元素
      • 127.0.0.1:6379> srem myset a
        (integer) 1
    4. spop——隨機(jī)返回并刪除key對應(yīng)的set中的一個(gè)元素
    5. suion——求給定key對應(yīng)的set并集
    6. sinter——求給定key對應(yīng)的set交集
  2. 有序集合類型 sortedset:不允許重復(fù)元素悉抵,且元素有順序.每個(gè)元素都會(huì)關(guān)聯(lián)一個(gè)double類型的分?jǐn)?shù)肩狂。redis正是通過分?jǐn)?shù)來為集合中的成員進(jìn)行從小到大的排序。

    1. 存儲(chǔ):zadd key score value
      • 127.0.0.1:6379> zadd mysort 60 zhangsan
        (integer) 1
      • 127.0.0.1:6379> zadd mysort 50 lisi
        (integer) 1
      • 127.0.0.1:6379> zadd mysort 80 wangwu
        (integer) 1
    2. 獲壤咽巍:zrange key start end [withscores] , -1表示獲取所有元素
      • 127.0.0.1:6379> zrange mysort 0 -1

        • "lisi"
        • "zhangsan"
        • "wangwu"
      • 127.0.0.1:6379> zrange mysort 0 -1 withscores

        • "zhangsan"
        • "60"
        • "wangwu"
        • "80"
        • "lisi"
        • "500"
    3. 刪除:zrem key value ,刪除key對應(yīng)的zset中的一個(gè)元素
      • 127.0.0.1:6379> zrem mysort lisi
        (integer) 1
    4. zrangebyscore——返回有序集key中傻谁,指定分?jǐn)?shù)范圍的元素列表,排行榜中運(yùn)用
    5. zrank——返回key對應(yīng)的zset中指定member的排名。其中member按score值遞增(從小到大)列粪;排名以0為底审磁,也就是說,score值最小的成員排名為0,排行榜中運(yùn)用

set是通過hashmap存儲(chǔ)岂座,key對應(yīng)set的元素态蒂,value是空對象;sortset是怎么存儲(chǔ)并實(shí)現(xiàn)排序的呢,hashmap存儲(chǔ)费什,還加了一層跳躍表;跳躍表:相當(dāng)于雙向鏈表钾恢,在其基礎(chǔ)上添加前往比當(dāng)前元素大的跳轉(zhuǎn)鏈接

  1. 通用命令
    1. keys * : 查詢所有的鍵
    2. type key : 獲取鍵對應(yīng)的value的類型
    3. del key:刪除指定的key value

  1. 持久化
    1. redis是一個(gè)內(nèi)存數(shù)據(jù)庫,當(dāng)redis服務(wù)器重啟鸳址,獲取電腦重啟瘩蚪,數(shù)據(jù)會(huì)丟失,我們可以將redis內(nèi)存中的數(shù)據(jù)持久化保存到硬盤的文件中稿黍。
    2. redis持久化機(jī)制:
      1. RDB:默認(rèn)方式疹瘦,不需要進(jìn)行配置,默認(rèn)就使用這種機(jī)制

        • 在一定的間隔時(shí)間中闻察,檢測key的變化情況拱礁,然后持久化數(shù)據(jù)
        1. 編輯redis.windwos.conf文件

          • after 900 sec (15 min) if at least 1 key changed
            save 900 1
          • after 300 sec (5 min) if at least 10 keys changed
            save 300 10
          • after 60 sec if at least 10000 keys changed
            save 60 10000
        2. 重新啟動(dòng)redis服務(wù)器,并指定配置文件名稱
          D:\JavaWeb2018\day23_redis\資料\redis\windows-64\redis-2.8.9>redis-server.exe redis.windows.conf

      2. AOF:日志記錄的方式辕漂,可以記錄每一條命令的操作呢灶。可以每一次命令操作后钉嘹,持久化數(shù)據(jù)

        1. 編輯redis.windwos.conf文件
          • appendonly no(關(guān)閉aof) --> appendonly yes (開啟aof)
          • appendfsync always : 每一次操作都進(jìn)行持久化
          • appendfsync everysec : 每隔一秒進(jìn)行一次持久化
          • appendfsync no : 不進(jìn)行持久化

事務(wù)

  1. Redis事務(wù)可以一次執(zhí)行多個(gè)命令鸯乃,按順序串行化執(zhí)行,且執(zhí)行過程中不許加塞;
    1. 批量操作在發(fā)送 EXEC 命令前被放入隊(duì)列緩存;
    2. 收到 EXEC 命令后,進(jìn)入事務(wù)執(zhí)行缨睡,事務(wù)中任何命令執(zhí)行失敗鸟悴,其余命令依然被執(zhí)行;
    3. 在事務(wù)執(zhí)行過程中,其他客戶端提交的命令請求不會(huì)插入到事務(wù)執(zhí)行序列中;
    4. 總的來說奖年,Redis會(huì)將一個(gè)事務(wù)中的所有命令序列化细诸,然后按順序執(zhí)行,且不允許出現(xiàn)加塞行為.
  2. 事務(wù)經(jīng)歷的三個(gè)階段:開啟事務(wù) --> 命令入列 --> 執(zhí)行事務(wù);
  3. A向B轉(zhuǎn)賬
    multi #開啟事務(wù)陋守,以后的命令會(huì)依次進(jìn)入到序列中
    get account:a
    get account:b
    decrby account:a 50 #A減50
    incrby account:b 50 #B加50
    exec #執(zhí)行事務(wù)
  4. discard:取消事務(wù)震贵,放棄隊(duì)列中的所有命令;開啟了事務(wù)水评,但不想執(zhí)行 exec 命令時(shí)猩系,可執(zhí)行 discard 命令取消事務(wù);
  5. 錯(cuò)誤處理:
    1. 如果隊(duì)列中的某個(gè)命令出現(xiàn)錯(cuò)誤,比如操作的key不存在中燥,屬于邏輯業(yè)務(wù)的錯(cuò)誤寇甸,那么這條命令不再執(zhí)行,
      而其他命令仍照常執(zhí)行疗涉,而且不會(huì)回滾;
    2. 但如果某個(gè)命令出現(xiàn)報(bào)告錯(cuò)誤(語法錯(cuò)誤)拿霉,比如輸入的命令不存在,Redis會(huì)立即報(bào)錯(cuò)博敬,那么Redis會(huì)取消事務(wù)友浸,
      所有命令都不會(huì)執(zhí)行;
  6. watch/unwatch
    1. 當(dāng)兩個(gè)事務(wù)同時(shí)操作同一個(gè)key時(shí),可能會(huì)導(dǎo)致數(shù)據(jù)的不一致;
    2. watch key key ... : 監(jiān)視key偏窝,在開啟事務(wù)之后收恢、執(zhí)行事務(wù)之前,這個(gè)key被其他命令改動(dòng)了祭往,
      那么當(dāng)前事務(wù)將會(huì)被打斷伦意,并回滾;
    3. unwatch:取消對所有key的監(jiān)視;
    4. 如果在執(zhí)行 watch 命令之后,只要執(zhí)行了 exec 或 discard 命令硼补,watch會(huì)自動(dòng)取消驮肉,無需再執(zhí)行 unwatch 命令.
  7. 應(yīng)用場景:
    1. 一組命令必須同時(shí)執(zhí)行,或者都不執(zhí)行;
    2. 保證一組命令在執(zhí)行過程中不被其他命令插入;
    3. 商品秒殺活動(dòng)已骇、轉(zhuǎn)賬;

為什么Redis回滾幾乎不用

Redis命令在事務(wù)中可能會(huì)執(zhí)行失敗离钝,但是Redis事務(wù)不會(huì)回滾,而是繼續(xù)會(huì)執(zhí)行余下的命令褪储。如果您有一個(gè)關(guān)系型數(shù)據(jù)庫的知識(shí)卵渴,這對您來說可能會(huì)感到奇怪,因?yàn)殛P(guān)系型數(shù)據(jù)在這種情況下都是會(huì)回滾的鲤竹。

Redis這樣做浪读,主要是因?yàn)?

只有當(dāng)發(fā)生語法錯(cuò)誤(這個(gè)問題在命令隊(duì)列時(shí)無法檢測到)了,Redis命令才會(huì)執(zhí)行失敗, 或?qū)eys賦予了一個(gè)類型錯(cuò)誤的數(shù)據(jù):這意味著這些都是程序性錯(cuò)誤,這類錯(cuò)誤在開發(fā)的過程中就能夠發(fā)現(xiàn)并解決掉碘橘,幾乎不會(huì)出現(xiàn)在生產(chǎn)環(huán)境互订。
由于不需要回滾,這使得Redis內(nèi)部更加簡單痘拆,而且運(yùn)行速度更快仰禽。

緩存問題

  1. 緩存穿透
    1. 查詢一個(gè)不存在數(shù)據(jù)時(shí),緩存中沒有错负,就需要從數(shù)據(jù)庫中查詢坟瓢,查不到數(shù)據(jù)就不寫入緩存中,導(dǎo)致每次請求
      這個(gè)不存在的數(shù)據(jù)時(shí)犹撒,都要到數(shù)據(jù)庫中去查詢,造成緩存穿透;
    2. 解決方式:持久層查詢不到數(shù)據(jù)時(shí)粒褒,就緩存一個(gè)空結(jié)果(空字符串)识颊,每次查詢時(shí)先判斷緩存中是否存在key,
      如果有奕坟,則直接返回空值祥款,表示此數(shù)據(jù)不存在,否則就去查詢數(shù)據(jù)庫;
    3. 另外月杉,持久層 insert 此數(shù)據(jù)時(shí)刃跛,及時(shí)清除查詢的key,或者設(shè)置空結(jié)果的緩存時(shí)間;
  2. 緩存雪崩
    1. 如果緩存集中在一段時(shí)間內(nèi)失效苛萎,發(fā)生大量的緩存穿透桨昙,所有的查詢都落在數(shù)據(jù)庫上,造成緩存雪崩;
    2. 緩存雪崩沒有完美的解決方案腌歉,應(yīng)分析用戶行為蛙酪,盡量將緩存失效時(shí)間均勻分布;
    3. 大多數(shù)系統(tǒng)設(shè)計(jì)者會(huì)考慮加鎖/分布式鎖,或者隊(duì)列的方式來保證單線程/進(jìn)程去寫緩存翘盖,從而避免失效時(shí)
      大量的并發(fā)請求落在數(shù)據(jù)庫上;
  3. 熱點(diǎn)key
    1. 某個(gè)key訪問非常頻繁桂塞,當(dāng)key失效時(shí),將會(huì)有大量線程來構(gòu)建緩存馍驯,導(dǎo)致負(fù)載增加阁危,系統(tǒng)崩潰;
    2. 解決方案:
      1. 使用鎖,單機(jī)使用synchronized汰瘫、lock等狂打,分布式使用分布式鎖;
      2. 不設(shè)置緩存過期時(shí)間,而是在對應(yīng)的value里設(shè)置一個(gè)時(shí)間吟吝,如果檢測到超過了這個(gè)時(shí)間菱父,則異步更新緩存;
      3. 在value里設(shè)置一個(gè)比過期時(shí)間t0小的過期時(shí)間t1,當(dāng)t1過期時(shí),延長t1浙宜,并更新緩存;
      4. 設(shè)置標(biāo)簽緩存官辽,并設(shè)置過期時(shí)間,標(biāo)簽緩存過期后粟瞬,異步更新實(shí)際緩存;
  4. 緩存預(yù)熱:在項(xiàng)目即將發(fā)布上線之前同仆,清空Redis數(shù)據(jù)庫,然后由開發(fā)者把所有的功能調(diào)試一遍裙品,
    這樣Redis中就有了一些緩存數(shù)據(jù)俗批,然后再發(fā)布項(xiàng)目,這樣做也是為了避免大量用戶同時(shí)去查詢MySQL數(shù)據(jù)庫了;

Java客戶端 Jedis

* Jedis: 一款java操作redis數(shù)據(jù)庫的工具.
* 使用步驟:
    1. 下載jedis的jar包
    2. 使用
            //1. 獲取連接
            Jedis jedis = new Jedis("localhost",6379);
            //2. 操作
            jedis.set("username","zhangsan");
            //3. 關(guān)閉連接
            jedis.close();

    
* Jedis操作各種redis中的數(shù)據(jù)結(jié)構(gòu)
    1. 字符串類型 string set get
        ```java
        //1. 獲取連接
            Jedis jedis = new Jedis();//如果使用空參構(gòu)造市怎,默認(rèn)值 "localhost",6379端口
            //2. 操作
            //存儲(chǔ)
            jedis.set("username","zhangsan");
            //獲取
            String username = jedis.get("username");
            System.out.println(username);
    
            //可以使用setex()方法存儲(chǔ)可以指定過期時(shí)間的 key value
            jedis.setex("activecode",20,"hehe");//將activecode:hehe鍵值對存入redis岁忘,并且20秒后自動(dòng)刪除該鍵值對
    
            //3. 關(guān)閉連接
            jedis.close();
        ``` 
             

    2. 哈希類型 hash : map格式   hset hget hgetAll
        ```java
        //1. 獲取連接
            Jedis jedis = new Jedis();//如果使用空參構(gòu)造,默認(rèn)值 "localhost",6379端口
            //2. 操作
            // 存儲(chǔ)hash
            jedis.hset("user","name","lisi");
            jedis.hset("user","age","23");
            jedis.hset("user","gender","female");
    
            // 獲取hash
            String name = jedis.hget("user", "name");
            System.out.println(name);
    
    
            // 獲取hash的所有map中的數(shù)據(jù)
            Map<String, String> user = jedis.hgetAll("user");
    
            // keyset
            Set<String> keySet = user.keySet();
            for (String key : keySet) {
                //獲取value
                String value = user.get(key);
                System.out.println(key + ":" + value);
            }
    
            //3. 關(guān)閉連接
            jedis.close();
        ```


    3. 列表類型 list : linkedlist格式区匠。支持重復(fù)元素 lpush / rpush lpop / rpop lrange start end : 范圍獲取
            
        ```java
        //1. 獲取連接
            Jedis jedis = new Jedis();//如果使用空參構(gòu)造干像,默認(rèn)值 "localhost",6379端口
            //2. 操作
            // list 存儲(chǔ)
            jedis.lpush("mylist","a","b","c");//從左邊存
            jedis.rpush("mylist","a","b","c");//從右邊存
    
            // list 范圍獲取
            List<String> mylist = jedis.lrange("mylist", 0, -1);
            System.out.println(mylist);
            
            // list 彈出
            String element1 = jedis.lpop("mylist");//c
            System.out.println(element1);
    
            String element2 = jedis.rpop("mylist");//c
            System.out.println(element2);
    
            // list 范圍獲取
            List<String> mylist2 = jedis.lrange("mylist", 0, -1);
            System.out.println(mylist2);
    
            //3. 關(guān)閉連接
            jedis.close();
        ```


    4. 集合類型 set  : 不允許重復(fù)元素 sadd smembers:獲取所有元素

        ```java
        //1. 獲取連接
            Jedis jedis = new Jedis();//如果使用空參構(gòu)造,默認(rèn)值 "localhost",6379端口
            //2. 操作
    
    
            // set 存儲(chǔ)
            jedis.sadd("myset","java","php","c++");
    
            // set 獲取
            Set<String> myset = jedis.smembers("myset");
            System.out.println(myset);
    
            //3. 關(guān)閉連接
            jedis.close();
        ```
    5. 有序集合類型 sortedset:不允許重復(fù)元素驰弄,且元素有順序 zadd zrange
        ```java
        //1. 獲取連接
            Jedis jedis = new Jedis();//如果使用空參構(gòu)造麻汰,默認(rèn)值 "localhost",6379端口
            //2. 操作
            // sortedset 存儲(chǔ)
            jedis.zadd("mysortedset",3,"亞瑟");
            jedis.zadd("mysortedset",30,"后裔");
            jedis.zadd("mysortedset",55,"孫悟空");
    
            // sortedset 獲取
            Set<String> mysortedset = jedis.zrange("mysortedset", 0, -1);
    
            System.out.println(mysortedset);
    
    
            //3. 關(guān)閉連接
            jedis.close();
        ```

jedis連接池: JedisPool

使用:

1. 創(chuàng)建JedisPool連接池對象
2. 調(diào)用方法 getResource()方法獲取Jedis連接
//0.創(chuàng)建一個(gè)配置對象
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(50);
config.setMaxIdle(10);
//1.創(chuàng)建Jedis連接池對象
JedisPool jedisPool = new JedisPool(config,"localhost",6379);
//2.獲取連接
Jedis jedis = jedisPool.getResource();
//3. 使用
jedis.set("hehe","heihei");
//4. 關(guān)閉 歸還到連接池中
jedis.close();

連接池工具類

public class JedisPoolUtils {

private static JedisPool jedisPool;
                
static{
 //讀取配置文件
    InputStream is = JedisPoolUtils.class.getClassLoader().getResourceAsStream  ("jedis.properties");
    //創(chuàng)建Properties對象
    Properties pro = new Properties();
    //關(guān)聯(lián)文件
    try {
        pro.load(is);
    } catch (IOException e) {
        e.printStackTrace();
    }
    //獲取數(shù)據(jù),設(shè)置到JedisPoolConfig中
    JedisPoolConfig config = new JedisPoolConfig();
    config.setMaxTotal(Integer.parseInt(pro.getProperty("maxTotal")));
    config.setMaxIdle(Integer.parseInt(pro.getProperty("maxIdle")));

    //初始化JedisPool
    jedisPool = new JedisPool(config,pro.getProperty("host"),Integer.parseInt(pro.getProperty("port")));
}
/**
 * 獲取連接方法
 */
public static Jedis getJedis(){
    return jedisPool.getResource();
}
}

Linux(Centos7)中安裝配置使用 Redis

  1. 檢查是否有 redis yum 源

  • yum search redis
  • yum info redis

  1. 安裝 epel 倉庫

EPEL (Extra Packages for Enterprise Linux)是基于 Fedora 的一個(gè)項(xiàng)目戚篙,為“紅帽系”的操作系統(tǒng)提供額外的軟件包五鲫,適用于 RHEL、CentOS 和 Scientific Linux.

yum install epel-release -y

  1. 安裝 redis 數(shù)據(jù)庫

  • yum info redis
  • yum install redis -y

  1. 安裝完畢后岔擂,使用下面的命令啟動(dòng) redis 服務(wù)

  • systemctl start redis
  • systemctl restart redis
  • systemctl enable redis

  1. linux 上面進(jìn)入 Redis 客戶端

redis-cli

Ubuntu使用編譯版本安裝

  • step1:下載

wget http://download.redis.io/releases/redis-3.2.8.tar.gz

  • step2:解壓

tar -zxvf redis-3.2.8.tar.gz

  • step3:復(fù)制位喂,放到usr/local/redis?錄下

sudo mv ./redis-3.2.8 /usr/local/redis/

  • step4:進(jìn)?redis?錄

cd /usr/local/redis/

  • step5:生成
    • 安裝c語言編譯器gcc: sudo apt-get install gcc
    • 安裝編譯命令make: sudo apt-get install make(這一步可能會(huì)出問題,根據(jù)提示執(zhí)行命令)
    • 生成 : sudo make(比較慢)
  • step6:測試,這段運(yùn)?時(shí)間會(huì)較?

sudo make test

會(huì)報(bào)錯(cuò):make test error2....

解決方案:

cd 
wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz
sudo tar xzvf tcl8.6.1-src.tar.gz  -C /usr/local/
cd  /usr/local/tcl8.6.1/unix/
sudo ./configure
sudo make(時(shí)間比較長)
sudo make install 
  • step7:安裝,將redis的命令安裝到/usr/local/bin/?錄

sudo make install (時(shí)間比較長)

  • step8:安裝完成后智亮,我們進(jìn)入目錄/usr/local/bin中查看,文件如下
a)redis-server      redis服務(wù)器
b)redis-cli          redis命令行客戶端
c)redis-benchmark  redis性能測試工具
d)redis-check-aof    AOF文件修復(fù)工具
e)redis-check-rdb    RDB文件檢索工具
  • step9:配置?件忆某,移動(dòng)到/etc/?錄下
    配置?件?錄為/usr/local/redis/redis.conf

sudo cp /usr/local/redis/redis.conf 空格 /etc/redis/

配置

  • Redis的配置信息在/etc/redis/redis.conf下。
  • 查看

sudo vi /etc/redis/redis.conf

核心配置選項(xiàng)

  • 綁定ip:如果需要遠(yuǎn)程訪問阔蛉,可將此?注釋弃舒,或綁定?個(gè)真實(shí)ip

bind 127.0.0.1

  • 端?,默認(rèn)為6379

port 6379

  • 是否以守護(hù)進(jìn)程運(yùn)?
    • 如果以守護(hù)進(jìn)程運(yùn)?状原,則不會(huì)在命令?阻塞聋呢,類似于服務(wù)
    • 如果以?守護(hù)進(jìn)程運(yùn)?,則當(dāng)前終端被阻塞
    • 設(shè)置為yes表示守護(hù)進(jìn)程颠区,設(shè)置為no表示?守護(hù)進(jìn)程
    • 推薦設(shè)置為yes

    daemonize yes

  • 數(shù)據(jù)?件

dbfilename dump.rdb

  • 數(shù)據(jù)?件存儲(chǔ)路徑

dir /var/lib/redis

  • ?志?件

logfile /var/log/redis/redis-server.log

  • 數(shù)據(jù)庫削锰,默認(rèn)有16個(gè)

database 16

  • 主從復(fù)制,類似于雙機(jī)備份毕莱。

slaveof

啟動(dòng)服務(wù)端

此時(shí)啟動(dòng)針對編譯安裝版本的啟動(dòng)

  • cd /etc/redis/redis-server
  • ./redis.conf

啟動(dòng)客戶端

redis-cli

測試是否是通的

ping

返回pong則證明通暢

關(guān)閉

查詢r(jià)edis是否已經(jīng)啟動(dòng)

ps aux | grep redis

ps aux代表顯示所有進(jìn)程器贩,|是代表?xiàng)l件颅夺,grep是過濾然后是和redis有關(guān)的進(jìn)程。

  • 然后通過查詢回來的pid進(jìn)行關(guān)閉

sudo kill -9 23113/pid

默認(rèn)指令

不修改配置文件的情況下蛹稍,默認(rèn)使用如下指令即可

  • 推薦使?服務(wù)的?式管理redis服務(wù)
  • 啟動(dòng)

sudo service redis start

  • 停?

sudo service redis stop

  • 重啟

sudo service redis restart

但是修改配置文件之后就用不了了吧黄,一般推薦如下:

ps -aux|grep redis 查看redis服務(wù)器進(jìn)程
sudo kill -9 pid 殺死redis服務(wù)器
sudo redis-server /etc/redis/redis.conf 指定加載的配置文件

注意

如果以 redis start形式開啟redis,并且寫入數(shù)據(jù)唆姐,此時(shí)kill形式關(guān)閉拗慨,再已
找到配置文件形式啟動(dòng),則可能啟動(dòng)不成功奉芦,此時(shí)可以 rm dump.rdb刪除redis本地?cái)?shù)據(jù)庫文件之后在啟動(dòng)赵抢。原因是兩種啟動(dòng)方式,一種使用存儲(chǔ)了另外一種大部分情況下不能操作數(shù)據(jù)庫文件声功,但是不是絕對的烦却。

go中使用redis

安裝命令

go get github.com/gomodule/redigo/redis

安裝完成后,回到家目錄創(chuàng)建test.go,把下面代碼復(fù)制到test.go里面先巴,編譯執(zhí)行test.go短绸,之后在redis中查找到鍵c1值為hello,說明安裝成功

package main
import ( "github.com/gomodule/redigo/redis")
func main(){
        conn,_ := redis.Dial("tcp", ":6379")
        defer conn.Close()
        conn.Do("set", "c1", "hello")
}

操作方法

Go操作redis文檔

  • 連接數(shù)據(jù)庫

Dial(network, address string)(conn,err)

  • 執(zhí)行數(shù)據(jù)庫操作命令
Send(commandName string, args ...interface{}) error
Flush() error
Receive() (reply interface{}, err error)

Send函數(shù)發(fā)出指令筹裕,flush將連接的輸出緩沖區(qū)刷新到服務(wù)器,Receive接收服務(wù)器返回的數(shù)據(jù)

例如:

c.Send("SET", "foo", "bar")
c.Send("GET", "foo")
c.Flush()//把緩沖區(qū)命令發(fā)到服務(wù)器
c.Receive() // 接收set請求返回的數(shù)據(jù)
v, err = c.Receive() // 接收get請求傳輸?shù)臄?shù)據(jù)

另外一種執(zhí)行數(shù)據(jù)庫操作命令

Do(commandName string, args ...interface{}) (reply interface{}, err error)

  • reply helper functions(回復(fù)助手函數(shù))

Bool窄驹,Int朝卒,Bytes,map乐埠,String抗斤,Strings和Values函數(shù)將回復(fù)轉(zhuǎn)換為特定類型的值。為了方便地包含對連接Do和Receive方法的調(diào)用丈咐,這些函數(shù)采用了類型為error的第二個(gè)參數(shù)瑞眼。如果錯(cuò)誤是非nil,則輔助函數(shù)返回錯(cuò)誤棵逊。如果錯(cuò)誤為nil伤疙,則該函數(shù)將回復(fù)轉(zhuǎn)換為指定的類型:

exists, err := redis.Bool(c.Do("EXISTS", "foo"))
if err != nil {
//處理錯(cuò)誤代碼
}
reflect.TypeOf(exists)//打印exists類型
  • Scan函數(shù)

func Scan(src [] interface {},dest ... interface {})([] interface {},error)

Scan函數(shù)從src復(fù)制到dest指向的值。
Dest參數(shù)的值必須是整數(shù)辆影,浮點(diǎn)數(shù)徒像,布爾值,字符串蛙讥,[]byte锯蛀,interface{}或這些類型的切片。Scan使用標(biāo)準(zhǔn)的strconv包將批量字符串轉(zhuǎn)換為數(shù)字和布爾類型次慢。

示例代碼

var value1 int
var value2 string
reply, err := redis.Values(c.Do("MGET", "key1", "key2"))
if err != nil {
    //處理錯(cuò)誤代碼
}
 if _, err := redis.Scan(reply, &value1, &value2); err != nil {
    // 處理錯(cuò)誤代碼
}

序列化與反序列化

針對redis旁涤,如果存儲(chǔ)復(fù)雜數(shù)據(jù)類型可以序列化之后存儲(chǔ)翔曲,取出后,反序列化獲取劈愚。一般都是利用Bytes存儲(chǔ)序列化的數(shù)據(jù)瞳遍。

  • 序列化(字節(jié)化)
var buffer bytes.Buffer//容器
enc :=gob.NewEncoder(buffer)//編碼器
err:=enc.Encode(dest)//編碼

反序列化(反字節(jié)化)

dec := gob.NewDecoder(bytes.NewReader(buffer.bytes()))//解碼器
dec.Decode(src)//解碼

Nodejs 中使用 Redis

  1. 在你的項(xiàng)目中安裝 Redis

npm install redis --save 或者 cnpm install redis --save

  1. 使用 Redis
字符串案例:
var redis = require('redis');
var client = redis.createClient(6379, 'localhost');
//設(shè)置數(shù)據(jù)
client.set('username', '李四');
client.set('username', '李四','EX','5'); //設(shè)置過期 5 秒
//獲取數(shù)據(jù)
client.get('username', function(err, val){
console.log(val);
});
列表案例:
var redis = require('redis');
var client = redis.createClient(6379, 'localhost');
client.rpush('testLists', 'a');
client.rpush('testLists', 'b');
client.rpush('testLists', 'c');
client.lpush('testLists', 2);
client.lpush('testLists', 1);
client.lrange('testLists',0, -1,(err,lists)=>{
if(err){
console.log(err);
return;
}
console.log(lists)
})
集合案例:
var redis = require('redis');
var client = redis.createClient(6379, 'localhost');
client.sadd('testSet', 1);
client.sadd('testSet', 'a');
client.sadd('testSet', 'bb');
client.smembers('testSet', function(err, v){
console.log(v);
});
哈希案例:
var redis = require('redis');
var client = redis.createClient(6379, 'localhost');
client.hset('userinfo',"username", "zhangsan");
client.hmset('userinfo',"username","張三","age", "20","sex","男");
client.hgetall('userinfo',function(err,val){
console.log(val);
})

Redis 訂閱發(fā)布


  • Redis 發(fā)布訂閱(pub/sub)是一種消息通信模式:發(fā)送者(pub)發(fā)送消息,訂閱者(sub)接收消息造虎。
  • redis發(fā)布訂閱功能比較薄弱但比較輕量級(jí)傅蹂,mq消息持久化,數(shù)據(jù)可靠性比較差算凿,無后臺(tái)功能可msgId份蝴、msgKey進(jìn)行查詢消息
  • Redis 客戶端可以訂閱任意數(shù)量的頻道。
  • 下圖展示了頻道 channel1 氓轰, 以及訂閱這個(gè)頻道的三個(gè)客戶端 —— client2 婚夫、 client5 和 client1之間的關(guān)系:

圖1.png

當(dāng)有新消息通過 PUBLISH 命令發(fā)送給頻道 channel1 時(shí), 這個(gè)消息就會(huì)被發(fā)送給訂閱它的三個(gè)客戶端

圖2.png
  • 發(fā)布

client.publish('testPublish', 'message from publish.js');

  • 訂閱
client.subscribe('testPublish');
client.on('message', function(channel, msg){
console.log('client.on message, channel:', channel, ' message:', msg);
});
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末署鸡,一起剝皮案震驚了整個(gè)濱河市案糙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌靴庆,老刑警劉巖时捌,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異炉抒,居然都是意外死亡奢讨,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門焰薄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拿诸,“玉大人,你說我怎么就攤上這事塞茅∧堵耄” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵野瘦,是天一觀的道長描沟。 經(jīng)常有香客問我,道長缅刽,這世上最難降的妖魔是什么啊掏? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮衰猛,結(jié)果婚禮上迟蜜,老公的妹妹穿的比我還像新娘。我一直安慰自己啡省,他們只是感情好娜睛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布髓霞。 她就那樣靜靜地躺著,像睡著了一般畦戒。 火紅的嫁衣襯著肌膚如雪方库。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天障斋,我揣著相機(jī)與錄音纵潦,去河邊找鬼。 笑死垃环,一個(gè)胖子當(dāng)著我的面吹牛邀层,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播遂庄,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼寥院,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了涛目?” 一聲冷哼從身側(cè)響起秸谢,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎霹肝,沒想到半個(gè)月后估蹄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡沫换,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年元媚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片苗沧。...
    茶點(diǎn)故事閱讀 39,902評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖炭晒,靈堂內(nèi)的尸體忽然破棺而出待逞,到底是詐尸還是另有隱情,我是刑警寧澤网严,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布识樱,位于F島的核電站,受9級(jí)特大地震影響震束,放射性物質(zhì)發(fā)生泄漏怜庸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一垢村、第九天 我趴在偏房一處隱蔽的房頂上張望割疾。 院中可真熱鬧,春花似錦嘉栓、人聲如沸宏榕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽麻昼。三九已至奠支,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間抚芦,已是汗流浹背倍谜。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留叉抡,地道東北人尔崔。 一個(gè)月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像卜壕,于是被迫代替她去往敵國和親您旁。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評論 2 354

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