Redis的安裝使用

1.Redis是什麼

Redis是一個使用ANSI C(C語言) 編寫的開源的高性能的Key-Value的NoSQL資料庫(非關係型資料庫)。
 

2.Redis特點

1.基於記憶體
2.可持久化數據
3.具有豐富的數據結構類型,適應非關係型數據的存儲需求
4.支援絕大多數主流開發語言,如C、C++、Java、Python、R、JavaScript等。
5.支援集群模式,高效、穩定。
 

3.數據模型(A)

1.鍵值對形式。
2.Redis的數據結構類型,指的就是Redis值的結構類型。
0

4.Redis作用

1.本質是資料庫,能存儲數據。
Redis能靈活處理非關係型數據的讀、寫問題,是對MySQL等關係型資料庫的補充。
新浪微博就是使用Redis集群做資料庫。
 
2.快取數據。
所謂快取,就是將數據載入到記憶體中後直接使用,而不是每次都通過IO流從磁碟上讀取。好處:讀寫效率高。
而Redis則是將數據直接存儲在記憶體中,只有當記憶體空間不足時,將部分數據持久化到磁碟上。
 

5.Redis安裝(Linux)

Redis官方只提供了源碼,並沒有提供經過編譯之後的安裝包。因此,安裝Redis,要先編譯、後安裝。(即源碼安裝方式)
 

5.1 redis安裝步驟

1.下載,上傳到Linux伺服器,並解壓
2.預編譯(實際上是檢查編譯環境的過程)
進入目錄: cd /opt/soft/redis-3.2.9/deps/jemalloc
執行預編譯 ./configure
在預編譯的過程中,會檢測安裝redis所需的相關依賴,依次安裝即可。
如:缺少c編譯環境 yum -y install gcc-c++
 
預編譯不是必須的步驟,它只是在檢查編譯過程中需要的環境是否滿足。通常源碼包中,都有一個可執行的configure腳本,這個腳本執行預編譯的腳本。但是有一些源碼包中,沒有該文件,可以省略預編譯步驟。
 
3.編譯 進入/opt/soft/redis-3.2.9/src
make
4.安裝 進入/opt/soft/redis-3.2.9/src
make install
5.啟動redis服務端(指定配置文件)
拷貝redis.conf文件到/etc 目錄下,方便管理。
cp /opt/soft/redis-3.2.9/redis.conf /etc/
/usr/local/bin/redis-server /etc/redis.conf
 
0
6.啟動redis客戶端,登陸 /usr/local/bin/redis-cli
0
 

6.redis.conf常用配置說明

6.1 requirepass (設置密碼)

給redis設置密碼
在/etc/redis.conf中設置密碼(退出redis登錄用quit)
0
找到上面這行程式碼改成
0
設置密碼後需要重新啟動redis服務端 才會生效
 
在客戶端使用auth命令,驗證密碼。
0
 

6.2 databases(資料庫)

Redis默認有16個資料庫,定址角標從0開始。
默認連接db0
0
客戶端使用select命令可切換資料庫
0
 

6.3 port(埠)

指定redis的服務埠,默認6379
0
 

6.4 daemonize(後台進程)

Redis默認關閉後台進程模式,改成yes,redis服務在後台啟動。
0
 
 

6.5 loglevel(日誌級別)

0
 

6.6 logfile(日誌輸出文件)

Redis日誌輸出目錄,默認不輸出日誌到文件。
0
 

6.7 dbfilename(持久化文件名)、 dir(文件路徑)

指定數據持久化的文件名及目錄。
0
 

7.將redis添加為系統服務

7.1 第一步:開啟後台模式

修改配置文件,將daemonize改為yes
 

7.2 第二步:創建shell腳本

Linux系統服務,在/etc/init.d目錄下創建redis腳本
###########################
#chkconfig: 2345 10 90
#description: Start and Stop redis
PATH=/usr/local/bin:/sbin:/usr/bin:/bin
   
REDISPORT=6379
EXEC=/usr/local/bin/redis-server
REDIS_CLI=/usr/local/bin/redis-cli
##判斷redis是否啟動了 
PIDFILE=/var/run/redis_6379.pid
CONF="/etc/redis.conf"
PASSWORD=$(cat $CONF|grep '^\s*requirepass'|awk '{print $2}'|sed 's/"//g')
   
case "$1" in
    start)
        if [ -f $PIDFILE ]
        then
                echo "$PIDFILE exists, process is already running or crashed"
        else
                echo "Starting Redis server..."
                $EXEC $CONF
        fi
        if [ "$?"="0" ]
        then
              echo "Redis is running..."
        fi
        ;;
    stop)
        if [ ! -f $PIDFILE ]
        then
                echo "$PIDFILE does not exist, process is not running"
        else
                PID=$(cat $PIDFILE)
                echo "Stopping ..."
if [ -z $PASSWORD ]
then 
    $REDIS_CLI -p $REDISPORT shutdown
else
    $REDIS_CLI -a $PASSWORD -p $REDISPORT shutdown
fi
                #$REDIS_CLI -p $REDISPORT SHUTDOWN
                while [ -x ${PIDFILE} ]
               do
                    echo "Waiting for Redis to shutdown ..."
                    sleep 1
                done
                echo "Redis stopped"
        fi
        ;;
   restart|force-reload)
        ${0} stop
        ${0} start
        ;;
  *)
    echo "Usage: /etc/init.d/redis {start|stop|restart|force-reload}" >&2
        exit 1
esac
##############################

7.3 第三步:添加shell腳本可執行許可權

chmod +x /etc/init.d/redis

7.4 第四步:添加Redis開機啟動

7.4 第四步:添加Redis開機啟動

8.Redis的值(value)的數據結構類型

一般說Redis的數據結構類型,指的就是redis的值value的類型;
Redis常用的數據結構類型:string、list、set、sortedSet、hash
 

9.Redis的使用

9.1 key的類型

redis的key 值是二進位安全的,這意味著可以用任何二進位序列作為key值,從形如」foo」的簡單字元串到一個JPEG文件的內容都可以。空字元串也是有效key值。
redis建議使用字元串做為key的類型
 

9.2 key取值規範

1.鍵值不需要太長,消耗記憶體,在數據中查找這類鍵值的計算成本較高
2.鍵值不宜過短,可讀性較差,通常建議見名知意。
例:user:id:1:username;user:id:1:password 。通過user:id:1*查詢。這就是一種命名方式(不一定要使用這種方式)
 

9.3 Key命令

 

 

9.4 string類型

string類型是redis最常用的數據結構類型,存儲的值為字元串。

string類型相關命令

 

 

String類型的應用場景

1.做與統計有關的業務,如新浪微博(微信朋友圈)中的點贊功能
2.解決多執行緒的執行緒安全問題。
Redis的key是單執行緒模式,這就意味一瞬間只有一個執行緒能夠持有這個key,所以可以使用redis解決部分涉及執行緒安全的業務,比如說搶購、秒殺。
再比如學習多執行緒時模擬買票窗口的賣票業務。
 

9.5 List類型

 

特點:

1.基於Linked List實現
2.元素是字元串類型
3.列表頭尾增刪快,中間增刪慢,增刪元素是常態
4.元素可以重複出現
5.最多包含2^32-1元素
列表的索引:從左至右,從0開始;從右至左,從-1開始
 

List類型相關命令

 

 

List類型應用場景

1.處理排名類業務。如新浪微博評論、論壇回帖樓層等。
2.聊天室
 

9.6 Hash類型(散列)

 

特點

0
1.由Field(欄位)和與之關聯的value組成map鍵值對
2.field和value是字元串類型;
3.一個hash中最多包含2^32-1鍵值對。
 

Hash相關命令

 

 

Hash的作用

節約記憶體空間:
redis每創建一個鍵,都會為這個鍵儲存一些附加的管理資訊(比如這個鍵的類型,這個鍵最後一次被訪問的時間等等)可以說redis的key相對於值來說,更珍貴!所以資料庫裡面的鍵越多,redis資料庫伺服器在儲存附加管理資訊方面耗費的記憶體就越多,在獲取key對應的value值時cpu的開銷也會更多 。
Hash結構可以將具有關聯關係的一組key-value,存儲到同一個hash結構中,從而減少key的數量。所以在能使用hash的時候盡量使用hash。
 
不適合使用Hash的場景
在需要只對hash中某個欄位設置過期時,就不建議使用hash。Redis的key的過期功能只能對鍵操作,而Hash結構不能單獨對某一個filed設置過期功能。
 

9.7 Set類型(集合)

特點

1.無序的、去重的;
2.元素是字元串類型;
3.最多包含2^32-1元素。
 

Set相關命令

 

 

Set應用場景

新浪微博的共同關注:當用戶訪問另一個用戶的時候,會顯示出兩個用戶共同關注哪些相同的用戶(交集)
 

9.8 SortedSet類型(有序集合)

特點

1.類似Set集合;
2.有序的、去重的;
3.元素是字元串類型;
4.每一個元素都關聯著一個浮點分數值(Score),並按照分數值從小到大的順序排列集合中的元素。分數值可以相同,相同時按字典順序排列
5.最多包含2^32-1元素
 

SortedSet類型相關命令

 

 

SortedSet類型適用場景

適用於需要有序且唯一的業務或操作:
如,網易音樂排行榜:
每首歌的歌名作為元素(唯一、不重複)
每首歌的播放次數作為分值
用zrevrange來獲取播放次數最多的歌曲(就是最多播放榜了,雲音樂熱歌榜,沒有競價,沒有權重)
 

10.使用Jedis連接redis伺服器

Jedis是Redis官方推薦的Java連接開發工具,可以通過java程式碼操作redis資料庫,就類似於jdbc
 

10.1 使用jedis連接redis可能會出現的問題及解決方案:

1.ip綁定問題
0
使用Jedis連接redis伺服器需要把Redis的配置文件redis.conf里的bind 127.0.0.1(或bind localhost)注釋掉,這句話的意思是僅允許本機才能訪問。我們需要讓redis伺服器允許其他主機訪問
0
 
2.保護模式(如果設置了密碼可以進行密碼驗證,不用關閉保護模式)
DENIED Redis is running in protected mode because protected mode is enabled…
關閉保護模式:把Redis的配置文件redis.conf中的protected-mode 的yes改成no
0
 

10.2 Jedis 相關jar包導入

 
0
 

10.3 Jedis連接redis服務端

package com.gjs.jedis;

import org.junit.Test;

import redis.clients.jedis.Jedis;

public class TestJedis {
    
    @Test
    public void testJedisConnect() throws Exception {
        //創建客戶端指定連接伺服器端主機ip和埠,埠不指定時默認使用6379
        Jedis jedis = new Jedis("192.168.192.128", 6379);
        System.out.println("連接redis伺服器端成功!");
        jedis.auth("1234"); //登錄驗證
        
        //測試連接
        System.out.println("redis伺服器是否運行:"+jedis.ping());
        System.out.println("redis伺服器資訊:"+jedis.info());
        
        //關閉連接
        jedis.close();
    }
}

10.4 Key測試

jedis類中大部分方法名都與對應的命令同名
@Test
    public void testKey() throws Exception {
        //創建客戶端指定連接伺服器端主機ip和埠,埠不指定時默認使用6379
        Jedis jedis = new Jedis("192.168.192.128", 6379);
        System.out.println("連接redis伺服器端成功!");
        //登錄驗證
        jedis.auth("1234");

        jedis.set("name", "zhangsan");//加入數據
        System.out.println("獲取key對應的值:"+jedis.get("name"));
        Set<String> keys = jedis.keys("*");//使用通配符進行模糊查詢
        System.out.println("獲取所有key的值:"+keys);
        //關閉連接
        jedis.close();        
    }

10.5 List測試

@Test
    public void testList() throws Exception {
        //創建客戶端指定連接伺服器端主機ip和埠,埠不指定時默認使用6379
        Jedis jedis = new Jedis("192.168.192.128", 6379);
        System.out.println("連接redis伺服器端成功!");
        //登錄驗證
        jedis.auth("1234");    
        
        jedis.lpush("list", new String[] {"a","c","b"});//添加數據
        Long len = jedis.llen("list");//獲取長度
        System.out.println("list長度:"+len);
        System.out.println("list元素:"+jedis.lrange("list", 0, len));
        System.out.println("指定索引位置的元素:"+jedis.lindex("list", 1));
        
        //關閉連接
        jedis.close();        
    }

10.6 Hash測試

@Test
    public void testHash() throws Exception {
        //創建客戶端指定連接伺服器端主機ip和埠,埠不指定時默認使用6379
        Jedis jedis = new Jedis("192.168.192.128", 6379);
        System.out.println("連接redis伺服器端成功!");
        //登錄驗證
        jedis.auth("1234");    
        //添加數據
        jedis.hset("user", "id", "1");
        jedis.hset("user", "name", "zhangsan");
        jedis.hset("user", "password", "123456");
        //獲取所有元素
        Map<String, String> user = jedis.hgetAll("user");
        System.out.println("獲取hash的所有欄位值:"+user);
        
        //關閉連接
        jedis.close();        
    }

10.7 Set測試

    @Test
    public void testSet() throws Exception {
        //創建客戶端指定連接伺服器端主機ip和埠,埠不指定時默認使用6379
        Jedis jedis = new Jedis("192.168.192.128", 6379);
        System.out.println("連接redis伺服器端成功!");
        //登錄驗證
        jedis.auth("1234");    
        //添加數據
        jedis.sadd("set1",new String[] {"a","s","d","f","g"});
        jedis.sadd("set2", new String[] {"a","s","z","x"});
        //獲取所有元素
        Set<String> set1 = jedis.smembers("set1");
        System.out.println("獲取set的所有元素:"+set1);
        
        System.out.println("獲取元素數量:"+jedis.scard("set1"));
        
        //獲取交並補集,方法參數是可變的
        Set<String> inter = jedis.sinter("set1","set2");
        System.out.println("獲取交集:"+inter);
        Set<String> union = jedis.sunion("set1","set2");
        System.out.println("獲取並集:"+union);
        Set<String> diff = jedis.sdiff("set1","set2");
        System.out.println("獲取差集:"+diff);
        
        //關閉連接
        jedis.close();        
    }

10.8 SortedSet測試

    @Test
    public void testSortedSet() throws Exception {
        //創建客戶端指定連接伺服器端主機ip和埠,埠不指定時默認使用6379
        Jedis jedis = new Jedis("192.168.192.128", 6379);
        System.out.println("連接redis伺服器端成功!");
        //登錄驗證
        jedis.auth("1234");    
        
        //添加數據
        Map<String, Double> scoreMembers = new HashMap<>();
        scoreMembers.put("a", 1d);
        scoreMembers.put("b", 3d);
        scoreMembers.put("c", 2d);
        jedis.zadd("sortSet", scoreMembers);
        //獲取數據
        //獲取分數值在指定區間的元素並按分數值由小到大排序
        Set<String> zrange = jedis.zrange("sortSet", 0, 3);
        System.out.println(zrange);
        
        //關閉連接
        jedis.close();        
    }

 

11.Redis持久化

Redis持久化,就是將記憶體中的數據,永久保存到磁碟上。
Redis持久化有兩種方式:RDB(Redis DB)、AOF(AppendOnlyFile)。
 

11.1 RDB(快照模式)

在默認情況下,Redis 將資料庫快照保存在名字為dump.rdb的二進位文件中,可以在redis.conf配置文件中修改持久化資訊。
0
save 900 1 表示在900秒內,至少更新了1條數據。Redis就將數據持久化到硬碟
save 300 10 表示在300內,至少更新了10條數據,Redis就會觸發將數據持久化到硬碟
save 60 10000 表示60秒內,至少更新了10000條數據,Redis就會觸發將數據持久化到硬碟
 

11.1.1 策略

1.自動:BGSAVE
按照配置文件中的條件滿足就執行BGSAVE;非阻塞,Redis服務正常接收處理客戶端請求;
Redis會folk()一個新的子進程來創建RDB文件,子進程處理完後會向父進程發送一個訊號,通知它處理完畢,父進程用新的dump.rdb替代舊文件。
 
2.手動:SAVE
由客戶端(redis-cli)發起SAVE命令;阻塞Redis服務,無法響應客戶端請求;創建新的dump.rdb替代舊文件。
 

11.1.2 優點

1.執行效率高;
2.恢復大數據集速度較AOF快。
 

11.1.3 缺點

1.會丟失最近寫入、修改的而未能持久化的數據;
2.folk過程非常耗時,會造成毫秒級不能響應客戶端請求。
 

11.2 AOF(追加模式、文本重演)

AOF(Append only file),採用追加的方式保存,默認文件appendonly.aof。記錄所有的寫操作命令,在服務啟動的時候使用這些命令就可以還原資料庫。AOF默認關閉,需要在配置文件中手動開啟。
0
 

11.2.1 寫入機制

說明:AOF機制,添加了一個記憶體緩衝區(buffer)。
1.將內容寫入緩衝區
2.當緩衝區被填滿、或者用戶手動執行fsync、或者系統根據指定的寫入磁碟策略自動調用fdatasync命令,才將緩衝區里的內容真正寫入磁碟里。
3.在緩衝區里的內容未寫入磁碟之前,可能會丟失。
 

11.2.2 寫入磁碟的策略

appendfsync選項,這個選項的值可以是always、everysec或者no
0
Always:伺服器每寫入一個命令,就調用一次fdatasync,將緩衝區裡面的命令寫入到硬碟。這種模式下,伺服器出現故障,也不會丟失任何已經成功執行的命令數據
Everysec(默認):伺服器每一秒重調用一次fdatasync,將緩衝區裡面的命令寫入到硬碟。這種模式下,伺服器出現故障,最多只丟失一秒鐘內的執行的命令數據
No:伺服器不主動調用fdatasync,由作業系統決定何時將緩衝區裡面的命令寫入到硬碟。這種模式下,伺服器遭遇意外停機時,丟失命令的數量是不確定的
運行速度:always的速度慢,everysec和no都很快
 

11.2.3 AOF重寫機制

AOF文件過大,合併重複的操作,AOF會使用儘可能少的命令來記錄。

重寫過程

1.folk一個子進程負責重寫AOF文件
2.子進程會創建一個臨時文件寫入AOF資訊
3.父進程會開闢一個記憶體緩衝區接收新的寫命令
4.子進程重寫完成後,父進程會獲得一個訊號,將父進程接收到的新的寫操作由子進程寫入到臨時文件中
5.新文件替代舊文件
重寫的本質:就是將操作同一個鍵的命令,合併。從而減小AOF文件的體積
0
 

AOF重寫觸發機制

1.手動:客戶端向伺服器發送BGREWRITEAOF命令
2.自動:配置文件中的選項,自動執行BGREWRITEAOF命令
 
0
auto-aof-rewrite-min-size ,
觸發AOF重寫所需的最小體積:只要在AOF文件的體積大於等於size時,才會考慮是否需要進行AOF重寫,這個選項用於避免對體積過小的AOF文件進行重寫
auto-aof-rewrite-percentage
指定觸發重寫所需的AOF文件體積百分比:當AOF文件的體積大於auto-aof-rewrite-min-size指定的體積,並且超過上一次重寫之後的AOF文件體積的percent %時,就會觸發AOF重寫。(如果伺服器剛剛啟動不久,還沒有進行過AOF重寫,那麼使用伺服器啟動時載入的AOF文件的體積來作為基準值)。將這個值設置為0表示關閉自動AOF重寫。
 

11.2.4 優點

寫入機制:默認Everysec每秒執行,性能很好不阻塞服務,最多丟失一秒的數據;
重寫機制:優化AOF文件,如果誤操作了(FLUSHALL等),只要AOF未被重寫,停止服務移除AOF文件尾部FLUSHALL命令,重啟Redis,可以將數據集恢復到FLUSHALL 執行之前的狀態。
 

11.2.5 缺點

1.相同數據集,AOF文件體積較RDB大了很多;
2.恢復資料庫速度較RDB慢(文本,命令重演)。
 
 
Tags: