天天看點

linux redis安裝及JAVA使用jedis

一、redis安裝

1.安裝redis

  将redis安裝包放到指定目錄下。并用tar -zxvf redis.*****.tar.gz解壓

2.想把redis安裝到哪裡,就在哪裡建立redis檔案夾。

  如 mkdir /home/chx/allSoftCert/redis

2.進入解壓後的目錄内,如redis4.0.0

3.cd src

4.sudo make install PREFIX=/home/chx/allSoftCert/redis

5.cp ../redis.conf /home/allSoft/redis/

6.運作測試:./home/chx/allSoftCert/redis/bin/redis-server /home/chx/allSoftCert/redis/redis.conf

  錯誤:如果發生make[1]: Entering directory錯誤,則執行make distclean後再次安裝

7.開啟遠端的端口

  ptables -I INPUT -p tcp --dport 6379 -j ACCEPT

  iptables save

8.修改密碼

  vi /home/chx/allSoftCert/redis/redis.conf

注釋bind 127.0.0.1

修改 daemonize no 為 daemonize yes

解注釋 requirepass foobared 并修改為 requirepass 123456

9.接下裡就可以進行java測試了

import redis.clients.jedis.Jedis;

import redis.clients.jedis.JedisPool;

import redis.clients.jedis.JedisPoolConfig;

public class MainJedis {

private static final String REDIS_IP = "192.168.0.156";

private static final String REDIS_AUTH = "123456";

private static final int MAX_TOTAL = 100;//最大連接配接數

private static final int MAX_ID_LE = 10;//最大空閑數

private static final int REDIS_DUAN_KOU = 6379;

public static void main(String[] args) {

JedisPoolConfig config = new JedisPoolConfig();

config.setMaxTotal(MAX_TOTAL);//設定最大連接配接數

config.setMaxIdle(MAX_ID_LE);//設定最大空閑數

JedisPool pool = null;

Jedis jedis =null;

try {

pool = new JedisPool(config,REDIS_IP,REDIS_DUAN_KOU);

jedis = new Jedis(REDIS_IP,6379);

jedis.auth(REDIS_AUTH);

jedis.set("chx", "boy");

System.out.println(jedis.get("chx"));

}catch (Exception e) {

e.printStackTrace();

}finally {

if(jedis!=null) {

jedis.close();

}

if(pool!=null) {

pool.close();

}

}

}

}

pom.xml對應如下:

<project xmlns="http://maven.apache.org/POM/4.0.0"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>JedisTest</groupId>

<artifactId>firstJedis</artifactId>

<version>0.0.1-SNAPSHOT</version>

<packaging>jar</packaging>

<name>firstJedis</name>

<url>http://maven.apache.org</url>

<properties>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

</properties>

<dependencies>

<dependency>

<groupId>redis.clients</groupId>

<artifactId>jedis</artifactId>

<version>2.9.0</version>

</dependency>

</dependencies>

</project>

 二、JAVA中使用redis

1.java對象存儲在redis内。

兩種方式:

(1).序列化和反序列化。

(2).轉換為json存儲。

2.redis的幾種資料結構

String: 字元串

Hash: 散列

List: 清單

Set: 集合

Sorted Set: 有序集合

3.Jedis基礎指令

jedis.del("key","key2");//删除key

jedis.auth(REDIS_AUTH);//操作密碼

jedis.set("chx", "boy");//放入普通的key-value

jedis.exists("chx");//判斷是否存在某個key

System.out.println("系統中所有鍵如下:");

//查詢系統所有key值

Set<String> keys = jedis.keys("*");

Iterator<String> it=keys.iterator();

while(it.hasNext()){

  System.out.println(it.next());

}

//設定key值的儲存時間,機關秒

jedis.expire("chx", 2);

//擷取key的存儲時間,永久生存或者不存在的都傳回-1

jedis.ttl("chx");

//移除key的生存時間

jedis.ttl("chx");

jedis.type("chx"));//檢視key所儲存的值的類

jedis.rename("old", "new");//修改key值

jedis.mset("chx2", "value2", "chx3", "value3");//一次性增加多個key-value

List<String> mget = jedis.mget("chx","chx1","chx2","chx3");//一次性擷取多個value

jedis.setnx("chx", "change");//放入key-value時防止覆寫舊值的方法

jedis.flushDB();//清空DB所有資料

Jedis 清單(List):

jedis.rpush("myList", "1","2","3","a");//從右邊添加,即尾插入

jedis.lrange("myList", 0, -1);//從左邊擷取

jedis.lrem("myList", 2, "1");//從左側删除2個值為1的資料

Jedis集合Set

System.out.println("清空庫中所有資料:" + jedis.flushDB());

jedis.sadd("mySet", "1","2","3");

System.out.println(jedis.smembers("mySet"));

Jedis hash

System.out.println("清空庫中所有資料:" + jedis.flushDB());

jedis.hset("myHash", "name", "chx");

Map<String, String> users = new HashMap<String, String>();

users.put("age", "18");

jedis.hmset("myHash", users)

System.out.println(jedis.hgetAll("myHash"));

  4.切片和非切片連接配接池的概念

    JedisPool連一台Redis,ShardedJedisPool連Redis叢集,通過一緻性雜湊演算法決定把資料存到哪台上。

5.redis有密碼的情況下關閉redis-server服務

  ./redis-cli -a 123456 shutdown

6.叢集下使用reids:

  檢視此文章

三、常用redis資料類型

1.字元串:

在Redis中字元串類型的Value最多可以容納的資料長度是512M。

set xx(key) xx(value),傳回OK,如果key存在會覆寫。

get xx(key),隻能擷取String 類型的,不是String 會報錯。

append key value:在原有的value後追加;如果該key不存在,則重新建立一個key/value。

msetnx key1 value1 key2 value2:如果key1存在,則key2也放不進去。隻有都不存在時才能放進去。

2.list:

lset xx(key) index xx(value):設定連結清單中的index的腳标的元素值,0-連結清單的頭元素,-1-連結清單的尾元素。

lrem key count value:删除count個值為value的元素,count>0,從頭向尾删除count個值為value的元素,count<0,則從尾向頭删除。如果count=0,則删除連結清單中所有等于value的元素。

linsert key before|after pivot value:在pivot元素前|後插入value。

3.set:

Set集合中不允許出現重複的元素。

smembers xx(key):擷取set中所有的成員。

scard xx(key):擷取set中成員的數量。

sismember xx(setX) xxv(value):判斷xxv是否在setX中,1存在,0不存在。

srem xx(setX) xxv(value):删除value。

sdiff set1 set2:傳回set1中set2沒有的資料(既差集,按順序傳回)。

4.Hash:

結構為hash(key)-field(多個)-value(多個)。

每一個Hash可以存儲 232 - 1 鍵值對(40多億)。

hset hash field value:為指定的hash設定field/value對(鍵值對)。如果哈希表不存在,将建立HASH并進行操作。設定成功傳回 1,覆寫傳回0。

hget hash field:傳回指定hash的key的值。

hexists hash field:判斷指定的hash中的field是否存在。

hlen hash:hash中field的數量。

四、分布式情況下存儲使用者狀态

當單台機器不能滿足性能提升時,大多采用分布式,但是session是基于cookie進行擷取的,導緻不同機器的jsessionid會不同,而導緻使用者通路不同機器時會重新登入。

是以一般用redis等記憶體存儲的資料庫進行session存儲。原理是将sessionid為key值,使用者資訊為value進行存儲。每次通路先去redis擷取使用者資訊,沒有說明是非法登入。同時redis可以設定資料的過期時間,由此可以基本實作原session功能。

五、Redis面試相關

Redis是高可用,NoSQL(not-only sql,泛指非關系型資料庫)的資料庫。

1.緩存穿透:就是由于大量通路不在redis的資料(比如非法傳入ID為-1),導緻每次都需要去資料庫查詢,導緻資料庫無法承載而崩潰。此時重新開機都無法解決,因為新的通路仍會導緻崩潰。這裡可以用布隆過濾器做處理,布隆過濾器是一個 bit 向量或者說 bit 數組,資料的hash的每個數值位(如Hash值等于147)散落在bit數組内。是以查詢時如果1、4、7位有值說明此資料可能存在(之是以不是一定存在是因為Hash沖突),1、4、7位不存在的則一定不存在。參考此文,非常不錯。

2.緩存雪崩:由于熱點資料(注意是熱點)同一時間失效,導緻大量通路湧入時都通路的資料庫而導緻崩潰。

3.緩存擊穿:由于一個熱點資料通路量過大,而此資料失效的瞬間導緻擊穿崩潰。

4.Redis是單線程,至于為什麼這麼快。首先由于Redis的操作都基于記憶體,是以讀寫耗時問題可以忽略,更多的是CPU及網絡帶寬影響其上下限,單線程避免了CPU不必要的上下文切換和競争條件,也避免了鎖的耗時問題。再者,Redis采用Key-Value存儲,基本讀是O(1)的時間複雜度。

5.有關主從複制:從節點僅提供讀操作,主節點提供寫操作。從節點中的定時任務發現主節點資訊,連接配接建立後,主節點将所有資料發送給從節點(資料同步)。主節點把目前的資料同步給從節點後,便完成了複制的建立過程。接下來,主節點就會持續的把寫指令發送給從節點,保證主從資料一緻性。

6.Redis分片及Hash槽相關:首先Redis采用Hash槽來确定資料配置設定到叢集的哪個主機,每個節點的槽位(如0-5000)是需要人工配置的,最大槽位為2的14次方即16384。第一個槽位和最後一個槽位相連,形成一個圓環,需要放入新資料時,利用crc16求出hash值,對16384求餘而确定放入那個節點。之是以不用一緻性hash是為了避免資料傾斜問題。參考此篇文章。是以每次擴充或當機時,隻需要把該節點的所有槽位轉移到新節點即可。

7.有關哨兵:哨兵是一個獨立的程序,顧名思義,哨兵主要用于監控-Master和Slave是否運作正常、提醒-通過API向管理者或者其他應用程式發送通知、自動故障遷移-将失效Master的其中一個Slave更新為新的Master(就像電視裡的巡邏、吹哨、發現危險拿起武器操作一番)。多個哨兵使用投票協定(agreement protocols)來決定是否執行自動故障遷移,以及選擇哪個Slave作為新的Master。

哨兵個數最少是三個,并且建議是奇數個。主要是為了投票主節點是否下線,少數服從多數。幾個哨兵投票為多數的配置,在sentinel.conf裡配置sentinel monitor開頭的一行,最後一個數字即是投票數。

哨兵預設端口号:26379  redis預設端口号6379

redis是沒有復原的。其事務主要是為了能夠全部執行正确的操作。如果在執行時出錯,如轉賬功能,是不會復原的(效率第一的理念)。但是運作前的入隊操作,有文法錯誤是不會送出的。

8.Redis持久化:就兩種,一種是RDB(Redis DataBase),一種是AOF(Append Only File)。

RDB:指定時間間隔内,将記憶體的資料集快照,儲存到磁盤。Redis會建立一個子程序,将快照寫入臨時檔案中,等到持久化結束就覆寫上一次的備份。此過程主程序不進行IO操作。如上所述,很有可能丢失最後一次備份。是以适合完整性和一緻性要求不高的情況,Fork時候是克隆目前主程序,導緻兩倍的記憶體占比,需要考慮記憶體配置。在Redis.conf可以配置檔案名及自動備份時間。

AOF:利用檔案儲存所有寫操作,隻追加不能修改,Redis重新開機就會讀取此檔案進行恢複。如果遇到斷電等aof檔案錯亂的情況,可以用redis-check-aof --fix 檔案名 來修複。是以也會丢失近一段時間的資料,不過一般比RDB丢失的少。在redis.conf裡可修改當占用多大存儲(auto-aof-rewrite-min-size 64mb 預設64兆)時進行壓縮及比上次膨脹百分比(auto-aof-rewrite-percentage 100預設100%),

9.事務:MULTI開始事務,添加指令(任何符合規範的指令get set等),EXEC執行事務。一個指令在錄入時失敗則全失敗(即EXEC之前失敗)!如果是運作時失敗則其他的是成功的!!

Watch 一個或多個key表示監視一個或多個key,執行exec指令後,鎖都被釋放。如果期間有其他人改動過這些key的value值,則事務被打斷。

10.關于ACID:原子性(Atomicity)、一緻性(Consistency)、隔離性(Isolation)、持久性(Durability)是相對于事務而言。Redis保證了資料的一緻性(記憶體模式下,重新開機後為空,不會一部分儲存一部分未儲存)、隔離性(單線程不涉及其他事務),實作了部分原子性(如第九條,EXEC可以在運作失敗時完成其他成功語句),但是沒有持久性,因為Redis事務執行過程中如果崩潰,不一定能夠恢複。