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慢(文本,命令重演)。
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM