1. 程式人生 > >redis系列——基本應用

redis系列——基本應用

一、基本介紹

1、NoSql介紹

        為了解決高併發、高可用、高可擴充套件,大資料儲存等一系列問題而產生的資料庫解決方案,就是NoSql。NoSql,叫非關係型資料庫,它的全名Not only sql。它不能替代關係型資料庫,只能作為關係型資料庫的一個良好補充。關係型資料庫中的表都是儲存一些結構化的資料,每條記錄的欄位的組成都一樣,即使不是每條記錄都需要所有的欄位,但資料庫會為每條資料分配所有的欄位。而非關係型資料庫以鍵值對(key-value)儲存,它的結構不固定,每一條記錄可以有不一樣的鍵,每條記錄可以根據需要增加一些自己的鍵值對,這樣就不會侷限於固定的結構,可以減少一些時間和空間的開銷。 其中Nosql資料庫分類如下:

  • 鍵值(Key-Value)儲存資料庫

相關產品: Tokyo Cabinet/Tyrant、Redis、Voldemort、Berkeley DB

典型應用: 內容快取,主要用於處理大量資料的高訪問負載。 

資料模型: 一系列鍵值對

優勢: 快速查詢

劣勢: 儲存的資料缺少結構化

  • 列儲存資料庫

相關產品:Cassandra, HBase, Riak

典型應用:分散式的檔案系統

資料模型:以列簇式儲存,將同一列資料存在一起

優勢:查詢速度快,可擴充套件性強,更容易進行分散式擴充套件

 劣勢:功能相對侷限

  • 文件型資料庫

相關產品:CouchDB、MongoDB

典型應用:Web應用(與Key-Value類似,Value是結構化的)

資料模型: 一系列鍵值對

 優勢:資料結構要求不嚴格

 劣勢: 查詢效能不高,而且缺乏統一的查詢語法

  • 圖形(Graph)資料庫

相關資料庫:Neo4J、InfoGrid、Infinite Graph

典型應用:社交網路

資料模型:圖結構

優勢:利用圖結構相關演算法。

劣勢:需要對整個圖做計算才能得出結果,不容易做分散式的叢集方案。

2、Redis介紹

1.基本說明

        Redis是用C語言開發的一個開源的高效能鍵值對(key-value)資料庫。它通過提供多種鍵值資料型別來適應不同場景下的儲存需求,目前為止Redis支援的鍵值資料型別如下:

  • 字串型別【String】
  • 雜湊型別【map】
  • 列表型別【list】
  • 集合型別【set】
  • 有序集合型別【sortedset】

2.歷史發展

        2008年,義大利的一家創業公司Merzia推出了一款基於MySQL的網站實時統計系統LLOOGG,然而沒過多久該公司的創始人 Salvatore Sanfilippo便 對MySQL的效能感到失望,於是他決定親自為LLOOGG量身定做一個數據庫,並於2009年開發完成,這個資料庫就是Redis。 不過Salvatore Sanfilippo並不滿足只將Redis用於LLOOGG這一款產品,而是希望更多的人使用它,於是在同一年Salvatore Sanfilippo將Redis開源釋出,並開始和Redis的另一名主要的程式碼貢獻者Pieter Noordhuis一起繼續著Redis的開發,直到今天。

        Salvatore Sanfilippo自己也沒有想到,短短的幾年時間,Redis就擁有了龐大的使用者群體。Hacker News在2012年釋出了一份資料庫的使用情況調查,結果顯示有近12%的公司在使用Redis。國內如新浪微博、街旁網、知乎網,國外如GitHub、Stack Overflow、Flickr等都是Redis的使用者。

        VMware公司從2010年開始贊助Redis的開發, Salvatore Sanfilippo和Pieter Noordhuis也分別在3月和5月加入VMware,全職開發Redis。

3.應用場景

  • 快取(資料查詢、短連線、新聞內容、商品內容等等)。(最多使用)
  • 分散式叢集架構中的session分離。
  • 聊天室的線上好友列表。
  • 任務佇列。(秒殺、搶購、12306等等)
  • 應用排行榜。
  • 網站訪問統計。
  • 資料過期處理(可以精確到毫秒)

二、Redis的安裝配置

1、redis的安裝

1.本地安裝

        redis會安裝到linux系統中,首先開啟Linux系統,並將redis的壓縮包上傳到linux系統中。之後對redis的壓縮包進行解壓縮(可以參考Linux的軟體安裝),Redis解壓縮之後的檔案是用c語言寫的原始碼檔案,然後進入安裝目錄並編譯redis原始碼:

 之後安裝redis,命令如下:

make install PREFIX=/opt/redis【opt目錄下,redis(自己取名)】

 然後進入該安裝目錄,檢視是否安裝成功

2.線上安裝

配置編譯環境:

sudo yum install gcc-c++

下載原始碼:

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

解壓原始碼:

tar -zxvf redis-4.0.9.tar.gz

進入到解壓目錄:

cd redis-4.0.9

執行make編譯Redis:

make MALLOC=libc

注意:make命令執行完成編譯後,會在src目錄下生成6個可執行檔案,分別是redis-server、redis-cli、redis-benchmark、redis-check-aof、redis-check-rdb、redis-sentinel。

安裝Redis:

make install PREFIX=/usr/local/InstallationSoftware/redis

2、 redis的啟動

1.前端啟動

前端啟動的命令為(首先進入bin目錄):

 

啟動介面如下 :

前端啟動的關閉:

  • 強制關閉:Ctrl+c
  • 正常關閉:./redis-cli shutdown

前端啟動的問題:一旦客戶端關閉,則redis服務也停掉。

2.後端啟動

        首先需要將redis解壓之後的原始碼包中的redis.conf檔案拷貝到bin目錄下:

然後使用vim修改redis.conf檔案

 將daemonize no改為daemonize yes

然後使用命令後端啟動redis

看是否啟動成功

 關閉後端啟動的方式為:

強制關閉:kill -9 7944

正常關閉:./redis-cli shutdown

注意:在專案中,建議使用正常關閉。因為redis作為快取來使用的話,將資料儲存到記憶體中,如果使用正常關閉,則會將記憶體資料持久化到本地之後,再關閉。如果是強制關閉,則不會進行持久化操作,可能會造成部分資料的丟失。

三、 redis.conf 的配置資訊

daemonize:如果需要在後臺執行,把該項改為yes

pidfile:配置多個pid的地址 預設在/var/run/redis.pid

bind:繫結ip,設定後只接受來自該ip的請求

port:監聽埠,預設是6379

loglevel:分為4個等級:debug verbose notice warning

logfile:用於配置log檔案地址

databases:設定資料庫個數,預設使用的資料庫為0

save:設定redis進行資料庫映象的頻率。

rdbcompression:在進行映象備份時,是否進行壓縮

dbfilename:映象備份檔案的檔名

Dir:資料庫映象備份的檔案放置路徑

Slaveof:設定資料庫為其他資料庫的從資料庫

Masterauth:主資料庫連線需要的密碼驗證

Requriepass:設定 登陸時需要使用密碼

Maxclients:限制同時使用的客戶數量

Maxmemory:設定redis能夠使用的最大記憶體

Appendonly:開啟append only模式

Appendfsync:設定對appendonly.aof檔案同步的頻率(對資料進行備份的第二種方式)

vm-enabled:是否開啟虛擬記憶體支援 (vm開頭的引數都是配置虛擬記憶體的)

vm-swap-file:設定虛擬記憶體的交換檔案路徑

vm-max-memory:設定redis使用的最大實體記憶體大小

vm-page-size:設定虛擬記憶體的頁大小

vm-pages:設定交換檔案的總的page數量

vm-max-threads:設定VM IO同時使用的執行緒數量

Glueoutputbuf:把小的輸出快取存放在一起

hash-max-zipmap-entries:設定hash的臨界值

Activerehashing:重新hash

四、Redis客戶端

1、Redis自帶的客戶端

        客戶端啟動命令為:

./redis-cli -h 127.0.0.1 -p 6379

 說明:

-h:指定訪問的redis伺服器的ip地址

-p:指定訪問的redis伺服器的port埠

此外還可以寫成:./redis-cli

使用預設配置:預設的ip【127.0.0.1】,預設的port【6379】

關閉方式為:Ctrl+c或者quit

2、圖形介面客戶端

        為windows程式,如下:

 安裝後建立連線如下:

連線後如下:

     預設一共是16個數據庫,每個資料庫之間是相互隔離。資料庫的數量是在redis.conf中配置的。如下:

預設將資料儲存到小標為0的資料庫中。切換資料庫使用命令:select 資料庫編號

退出為:quit

附加:如果無法訪問可能是Linux防火牆攔截了該埠,可以進行相關設定。解決辦法如下:

第一步:編輯iptables

vim /etc/sysconfig/iptables

在命令模式下,選定要複製的那一行的末尾,然後點選鍵盤yyp,就完成複製,然後修改。

 第二步:重啟防火牆

[[email protected] redis-3.0.0]# service iptables restart
iptables:清除防火牆規則:                                 [確定]
iptables:將鏈設定為政策 ACCEPT:filter                    [確定]
iptables:正在解除安裝模組:                                   [確定]
iptables:應用防火牆規則:                                 [確定]
[[email protected] redis-3.0.0]# 

如果還是無法訪問可能是開啟了保護模式,進入redis.conf檔案發現 bind 127.0.0.1配置,註釋該配置,重啟。如果還是連不上,在配置檔案中開啟密碼認證

#requirepass foobared  【foobared為密碼】

3、Java客戶端Jedis

1.jedis介紹

Redis不僅是使用命令來操作,現在基本上主流的語言都有客戶端支援,比如java、C、C#、C++、php、Node.js、Go等。在官方網站裡列一些Java的客戶端,有Jedis、Redisson、Jredis、JDBC-Redis、等其中官方推薦使用Jedis和Redisson。 在企業中用的最多的就是Jedis。 Jedis同樣也是託管在github上,地址:https://github.com/xetorthio/jedis 

2.使用舉例

        首先匯入jar包如下:

1.單例項連線

測試如下:

@Test
public void testJedis() {
    //建立一個Jedis的連線
    Jedis jedis = new Jedis("172.25.0.163", 6379);
    //執行redis命令
    jedis.set("mytest", "hello world, this is jedis client!");
    //從redis中取值
    String result = jedis.get("mytest");
    //列印結果
    System.out.println(result);
    //關閉連線
    jedis.close();
}

2.連線池連線

測試如下:

@Test
public void testJedisPool() {
    //建立一連線池物件
    JedisPool jedisPool = new JedisPool("172.25.0.163", 6379);
    //從連線池中獲得連線
    Jedis jedis = jedisPool.getResource();
    String result = jedis.get("mytest");
    System.out.println(result);
    //關閉連線
    jedis.close();
    //關閉連線池
    jedisPool.close();
}

3.Spring整合jedisPool

需要配置的spring檔案如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.2.xsd 
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
​
    <!-- 連線池配置 -->
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <!-- 最大連線數 -->
        <property name="maxTotal" value="30" />
        <!-- 最大空閒連線數 -->
        <property name="maxIdle" value="10" />
        <!-- 每次釋放連線的最大數目 -->
        <property name="numTestsPerEvictionRun" value="1024" />
        <!-- 釋放連線的掃描間隔(毫秒) -->
        <property name="timeBetweenEvictionRunsMillis" value="30000" />
        <!-- 連線最小空閒時間 -->
        <property name="minEvictableIdleTimeMillis" value="1800000" />
        <!-- 連線空閒多久後釋放, 當空閒時間>該值 且 空閒連線>最大空閒連線數 時直接釋放 -->
        <property name="softMinEvictableIdleTimeMillis" value="10000" />
        <!-- 獲取連線時的最大等待毫秒數,小於零:阻塞不確定的時間,預設-1 -->
        <property name="maxWaitMillis" value="1500" />
        <!-- 在獲取連線的時候檢查有效性, 預設false -->
        <property name="testOnBorrow" value="false" />
        <!-- 在空閒時檢查有效性, 預設false -->
        <property name="testWhileIdle" value="true" />
        <!-- 連線耗盡時是否阻塞, false報異常,ture阻塞直到超時, 預設true -->
        <property name="blockWhenExhausted" value="false" />
    </bean>
​
    <!-- redis單機 通過連線池 -->
    <bean id="jedisPool" class="redis.clients.jedis.JedisPool"
        destroy-method="close">
        <constructor-arg name="poolConfig" ref="jedisPoolConfig" />
        <constructor-arg name="host" value="192.168.242.130" />
        <constructor-arg name="port" value="6379" />
    </bean>
</beans>

然後測試類如下:

@Test
public void testJedisPool() {
    JedisPool pool = (JedisPool) applicationContext.getBean("jedisPool");
    Jedis jedis = null;
    try {
        jedis = pool.getResource();
​
        jedis.set("name", "lisi");
        String name = jedis.get("name");
        System.out.println(name);
    } catch (Exception ex) {
        ex.printStackTrace();
    } finally {
        if (jedis != null) {
            // 關閉連線
            jedis.close();
        }
    }
}