專家:亞馬遜 Prime Day 銷售額預計將達到近 100 億美元
Redis介紹
一種全新的記憶體型資料庫。
Redis是key-value型的NoSQL(Not only SQL)資料庫(非關係型資料庫);
Redis將資料儲存在記憶體中,同時也能持久化到磁碟;
Redis常用於快取,利用記憶體的高效提高程式的處理速度。
筆記:
記憶體RAM,關機重啟後資料會丟失,redis支援將資料持久化到硬碟上;
系統和資料庫服務直接可以增加redis伺服器,系統直接從redis中獲取資料,速度更快。
Redis特點
速度快;廣泛的語言支援;持久化;多種資料結構;主從複製;分散式於高可用。
筆記:
開源,可以根據需求開發特定的redis工具
高可用:哨兵機制,防止一臺redis伺服器當機系統就無法使用。
Redis的安裝與啟動
1)Linux系統上安裝Redis:
進入redis官網:https://redis.io/
因為redis是伺服器端的NoSQL資料庫,官方預設不會提供windows下的redis最新版本,只提供tar.gz格式tar.gz格式的redis最新版本的下載,所以redis的安裝平臺首選Linux系統。
點選Check the downloads page.
可以看到具體的安裝過程
步驟:
進入linux系統,開啟終端
cd /usr/local #進入local目錄,一般習慣將程式安裝在這個目錄下
mkdir redis #建立一個名為redis的資料夾,用於安裝 redis
cd redis #進入redis目錄
yum install gcc #底層依賴gcc才能使用make命令進行編譯,需先安裝gcc編譯包
wgethttp://download.redis.io/releases/redis-6.0.8.tar.gz#下載最新redis安裝包
tarxzf redis-6.0.8.tar.gz #解壓安裝包
cd redis-6.0.8/ #進入解壓後的目錄,裡面存放的是redis原始碼等,其中redis.conf是redis的核心配置檔案
make #編譯原始碼
cdsrc #進入原始碼目錄,其中redis-server是redis的啟動命令,redis-cli是redis的連線客戶端
cd .. #返回上一級目錄
./src/redis-server redis.conf #啟動redis
使用make編譯時報錯:
經查資料瞭解到,centos7安裝redis6.x版本要正常編譯,需要升級gcc的版本
gcc -v #檢視gcc版本
centos7預設gcc版本為4.8.5
redis6.x版本需要的gcc版本為5.3及以上
//升級gcc到9以上
yum -y install centos-release-scl
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
//臨時將此時的gcc版本改為9(scl命令啟用只是臨時的,推出xshell或者重啟就會恢復到原來的gcc版本)。
scl enable devtoolset-9 bash
//或永久改變
echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile
這時再查詢gcc版本,變為了9.x版本
重新使用make編譯,往下進行流程
看到下圖文字表示編譯成功:
redis啟動成功介面:
2)windows系統上安裝Redis:
微軟對redis重構,提供了能夠在windows上執行的redis。
github地址:https://github.com/MicrosoftArchive/redis
不過版本很久沒有更新了,截止目前,最後一次更新的才3.2.100版本
點選relese page
下載.zip版本,版本有些老,作為學習可以用,生產環境伺服器上不可以
解壓安裝包
redis-server.exe是啟動程式
redis-windows.conf是redis核心配置檔案
cmd進入終端
進入redis目錄,啟動redis,下圖是啟動成功介面。
reids的常用基本配置
Redis通用命令
筆記:
例1:守護程序方式啟動redis,即後臺執行
解決終端重啟或關閉後redis程序關閉的問題。
啟動linux終端,進入redis目錄:
cd redis-6.0.8/
開啟並編輯redis配置檔案:
vim redis.conf
定位到檔案的146行,將daemonize的引數由no改為yes,表示允許後臺啟動(按i進入編輯模式,修改後:wq儲存並退出)
關閉redis服務:
使用kill命令(不推薦,後續會學習使用redis-cli關閉命令)。
kill -9 程序號
例2:使用redis-cli客戶端
進入redis目錄:
cd redis-6.0.8/
啟動redis-cli,進入redis客戶端,可以輸入redis命令並執行:
./src/redis-cli
檢查redis服務是否正常啟動:
ping
ping 看是否能提供服務 ping 顯示pong正常
退出cli:
exit
使用cli關閉redis服務:
./src/redis-cli shutdown
實際專案一般不會用預設埠6379,防止黑客或第三方攻擊。通過修改redis.conf檔案來修改預設埠:
定位到配置檔案92行,修改port後的埠號
修改日誌檔名字(儲存在redis目錄下):
定位到171行,logfile ,預設為空字串
重新啟動redis可以看到變化:
後臺啟動,埠號為6380
這時,再連線cli客戶端,提示6379連線被拒絕,因為我們把埠改為了6380,需要連線6380埠。
在cli中操作redis資料庫:
select 資料庫名字 #切換資料庫
redis中資料庫的名字就是一個一個的數字 預設16個 序號0~15,超過會提示越界
修改cong配置檔案來修改資料庫總數:
定位到186行。
但這樣只要加上埠號就可以通過redis-cli訪問資料很危險,需要設定密碼:
定位到conf配置檔案507行。
把 requirepass 那一行註釋開啟,修改密碼
這樣就必須提供密碼才能訪問redis資料了。
cli連線身份驗證:
auth 密碼
指定資料檔案的儲存路徑修改,很重要,但很少修改,預設是當前資料夾:
定位到conf配置檔案第263行
redis目錄中的另一個重要檔案:
dump.rdb 檔案,用來儲存的全量資料(包含任何操作),防止redis突然當機造成資料丟失。
Redis資料型別
1)String-字串型別
結構:
命令:
單個kv不要太大,否則會影響存取資料的速度、效率;
value是數字時,底層也是以字串型別儲存的。
2)Hash鍵值型別
結構:
用於儲存結構化資料。
命令:
3)List列表型別
結構:
List列表就是一系列字串的“陣列”,按插入順序排列;
List列表最大長度為2的32次方-1,可以包含40億個元素。
命令:
lrange 獲取list中資料,後面兩個引數是開始範圍 start end,取全部值引數為 0 -1
4)Set集合型別
結構:
Set集合是字串的無序集合,集合成員是唯一的。
命令:
sadd 集合名字 字串(陣列) #建立一個集合,插入成員
smembers 集合名字 #檢視某集合所有成員
插入成員時,返回1表示插入成功,返回0表示失敗
集合求交集:
sinter 集合1 集合2
集合求並集:
sunion 集合1 集合2
集合求差集(1有,2沒有的):
sdiff 集合1 集合2
5)Zset集合型別
結構:
Zset集合是字串的有序集合,集合成員是唯一的。在Set集合基礎上加了一個分數引數,使集合有序。
預設按照分數升序排列。
命令:
zadd 集合名字 分數 字串 #建立一個集合,插入成員
zrange 集合名字 start end #用於輸出指定範圍的元素,0 -1 表示全部元素
Redis的Java客戶端——Jedis
redis官網為每種語言都提供了對應的客戶端,Jedis是Java語言開發的Redis客戶端工具包;
Jedis只是對Redis命令的封裝,掌握Redis命令便可以輕鬆上手。
1)Jedis使用演示
一般redis伺服器僅做redis服務使用,我們的java程式要用另外一臺伺服器。
多個伺服器之間進行來回通訊,redis的配置要進行一些更改。
1⃣️預設情況下只允許在本機訪問redis,要想遠端訪問需要修改兩個引數:
定位到conf檔案88行,protected-mode 保護模式,yes表示只允許指定的地址才能訪問redis服務,
開發需要,要先設定為no,允許其他主機也能訪問redis。
定位到69行,bind 預設 127.0.0.1 後面的地址表示能訪問redis的主體ip
修改為 bind 0.0.0.0 所有主機可訪問,實際專案不能這樣,不安全,要設定成具體伺服器地址
2⃣️設定防火牆對6379埠放行
正常第一次放行是不會有紅色warning的,這裡是因為之前已經放行了,所以才warning提示。
3⃣️檢視redis伺服器IP地址,聯機時需要用到
ifconfig
4⃣️下載安裝jedis
進入redis官網,點選Clients
點選java
裡面有許多開源的redis java客戶端,點選圖示,進入github官網
裡面有安裝的方式,下面使用maven方式下載
目前最新版本為3.3.0版本
2.9.0版本最穩定,暫用這一版本。
5⃣️jedis使用入門
啟動idea➡️create new project➡️maven➡️next
在pom檔案中加入redis依賴
測試程式碼:
1 public class JedisTestor { 2 public static void main(String[] args) { 3 Jedis jedis = new Jedis("192.168.132.144" , 6379);//伺服器地址,埠號 4 try { 5 jedis.auth("12345");//驗證密碼 6 jedis.select(2);///切換到資料庫2 7 System.out.println("Redis連線成功"); 8 //字串 9 jedis.set("sn" , "7781-9938"); 10 String sn = jedis.get("sn"); 11 System.out.println(sn); 12 jedis.mset(new String[]{"title" , "嬰幼兒奶粉" , "num" , "20"}); 13 List<String> goods = jedis.mget(new String[]{"sn" , "title" , "num"}); 14 System.out.println(goods); 15 Long num = jedis.incr("num"); 16 System.out.println(num); 17 //Hash 18 jedis.hset("student:3312" , "name" , "張曉明"); 19 String name = jedis.hget("student:3312" , "name"); 20 System.out.println(name); 21 Map<String,String> studentMap = new HashMap(); 22 studentMap.put("name", "李蘭"); 23 studentMap.put("age", "18"); 24 studentMap.put("id", "3313"); 25 jedis.hmset("student:3313", studentMap); 26 Map<String,String> smap = jedis.hgetAll("student:3313"); 27 System.out.println(smap); 28 //List 29 jedis.del("letter"); 30 jedis.rpush("letter" , new String[]{"d" , "e" , "f"}); 31 jedis.lpush("letter" , new String[]{"c" , "b" , "a"}); 32 List<String> letter = jedis.lrange("letter" , 0 , -1); 33 jedis.lpop("letter"); 34 jedis.rpop("letter"); 35 letter = jedis.lrange("letter", 0, -1); 36 System.out.println(letter); 37 }catch(Exception e){ 38 e.printStackTrace(); 39 }finally { 40 jedis.close();//關閉jedis連線 41 } 42 43 } 44 }
注意:redis中1個漢子3個位元組,一個字串返回的長度也是按位元組來算的
2)利用Jedis快取資料
用redis做快取,需具備的特性:資料不能太大,且更新頻率比較低的資料
將java物件存入redis(轉換為json存,用時在將json轉換回來,需要用到fastjson)
測試程式碼:
1 public class CacheSample { 2 public CacheSample(){ 3 Jedis jedis = new Jedis("192.168.132.144");//如果是預設埠號6379,可以不寫第二個引數 4 try { 5 List<Goods> goodsList = new ArrayList<Goods>(); 6 goodsList.add(new Goods(8818, "紅富士蘋果", "", 3.5f)); 7 goodsList.add(new Goods(8819, "進口臍橙", "", 5f)); 8 goodsList.add(new Goods(8820, "進口香蕉", "", 25f)); 9 jedis.auth("12345"); 10 jedis.select(3); 11 for (Goods goods : goodsList) { 12 String json = JSON.toJSONString(goods); 13 System.out.println(json); 14 String key = "goods:" + goods.getGoodsId(); 15 jedis.set(key , json); 16 } 17 } catch (Exception e) { 18 e.printStackTrace(); 19 }finally { 20 jedis.close(); 21 } 22 } 23 24 public static void main(String[] args) { 25 new CacheSample(); 26 System.out.printf("請輸入要查詢的商品編號:"); 27 String goodsId = new Scanner(System.in).next(); 28 Jedis jedis = new Jedis("192.168.132.144"); 29 try{ 30 jedis.auth("12345"); 31 jedis.select(3); 32 String key = "goods:" + goodsId; 33 if(jedis.exists(key)){ 34 String json = jedis.get(key); 35 System.out.println(json); 36 Goods g = JSON.parseObject(json, Goods.class);//將json轉換為Goods類物件 37 System.out.println(g.getGoodsName()); 38 System.out.println(g.getPrice()); 39 }else{ 40 System.out.println("您輸入的商品編號不存在,請重新輸入!"); 41 } 42 }catch(Exception e){ 43 e.printStackTrace(); 44 }finally { 45 jedis.close(); 46 } 47 } 48 }
java物件
1 public class Goods { 2 private Integer goodsId; 3 private String goodsName; 4 private String description; 5 private Float price; 6 7 public Goods(){ 8 9 } 10 11 public Goods(Integer goodsId, String goodsName, String description, Float price) { 12 this.goodsId = goodsId; 13 this.goodsName = goodsName; 14 this.description = description; 15 this.price = price; 16 } 17 18 public Integer getGoodsId() { 19 return goodsId; 20 } 21 22 public void setGoodsId(Integer goodsId) { 23 this.goodsId = goodsId; 24 } 25 26 public String getGoodsName() { 27 return goodsName; 28 } 29 30 public void setGoodsName(String goodsName) { 31 this.goodsName = goodsName; 32 } 33 34 public String getDescription() { 35 return description; 36 } 37 38 public void setDescription(String description) { 39 this.description = description; 40 } 41 42 public Float getPrice() { 43 return price; 44 } 45 46 public void setPrice(Float price) { 47 this.price = price; 48 } 49 }View Code
報錯:
connection refused
原因:
1.伺服器地址錯了
2.物理網路沒有調通