JT項目-3--數據分佈式存儲--hash一致性

DAY05

知識回顧+遺留問題

2018115

19:32

前4天的脈絡

 

 

複習的順序:將其中的所有非代碼技術先複習

把代碼敲一遍,分別的引入技術

 

1 nginx 一個服務器7萬/秒 轉發 併發 5萬 3萬

是京淘中提升併發的第一道關卡

20nginx集羣就可以搞定每秒100萬併發

 

2 屬性注入

擴展Bean加載數據

後處理bean注入擴展類把數據傳遞給僞service

後臺controller圖片上傳注入僞service使用屬性

 

3 nginx的匹配規則(與優先級)

· 精確匹配=

· 字符串前綴匹配 ^~

· 按照配置順序的正則匹配(AB都匹配上了,配置在前的匹配)

· 不帶任何修飾的前綴匹配/images/

· 當所有匹配成功時,停止匹配,按照當前匹配規則處理請求

· 前綴匹配,有包含關係時,按最大匹配長度原則匹配

· 最低優先級是通配符 /

location = /images{

return 205;}

 

location ^~ /images {

   return 200;}

location ^~ /images/test.png {

return 201;}

location ~* \.png$ {

   return 203;}

location ~ \.(gif|jpg|png|js|css)$ {

return 202;}

location / {

   return 204;}

 

http://localhost/ 返回204

http://localhost/images 205204?

http://localhost/images/id 200

http://localhost/images/test.png 返回201 前綴最長匹配原則

http://localhost/haha.png 返回203 順序正則原則

 

4 nginx負載均衡

輪詢:將所有的訪問平均分配給服務器庫中配置的服務器;

 

 

 

 

nginx負載均衡

2018116

10:05

 

權重:

根據不同機器性能,計算相對的訪問負載承受,從而使用權重配置

負載的量

upstream jt1710{

server 192.168.40.170:8081 ;

server 192.168.40.170:8082 ;

server 192.168.40.170:8080 ;

server 192.168.40.170:8081 ;

server 192.168.40.170:8081 ;

server 192.168.40.170:8081 ;

server 192.168.40.170:8081 ;

server 192.168.40.170:8081 ;}

權重的關鍵字

weight:權重的優先量級;數字越大,訪問次數越多

down;宕機狀態永不訪問;

當服務器宕機不可恢復時,nginx會根據權重或者輪詢配置

繼續訪問,連接超時訪問失敗,但是不會停止訪問,

down一定程度的減少了資源的損耗

session黏着

負載均衡中的session共享問題

 

解決session共享問題

session黏着

當用戶通過ngnix訪問某一個tomcat後,使用session黏着,保證後續訪問永遠

訪問者一臺

1 ip_hash

利用客戶端請求的ip和端口(192.168.40.170:661)獲取其字符串的hash值

String str="192.168.40.160:8080";

str.hashCode();(未必是正值,&Integer.max_value)

System.out.println(user1.hashCode()&Integer.MAX_VALUE);

System.out.println(user2.hashCode()&Integer.MAX_VALUE);

System.out.println(user3.hashCode()&Integer.MAX_VALUE);

獲取到字符串的整數然後對已有的負載均衡服務器庫數量進行取餘(三臺爲例)

哈希整數N%3=[0,1,2]

如果是4臺呢?對4取餘,依次類推

2 url_hash黏着(依賴第三方插件實現)

訪問服務器的url地址字符串做hash取餘運算

order.jt.com/*****/***.html

具有某一個固定功能的服務器,固定

 

springSession(HttpSession+redis)

 

將虛擬機中的後臺系統做完全,還差訪問數據庫

需要修改war包中的jdbc.properties

需要獲取linux系統訪問windows系統的ip地址

 

 

 

 


 

 

 

 

商品描述

2018116

10:57

查看電商中的描述信息,需要大字段屬性保存圖片信息和文本信息

blob/text破壞表的索引,商品描述不能添加到商品列表中

單獨創建一個商品描述表格 tb_item_desc

 

 

開發過程

pojo,mapper,service,controller

 

service不用單獨編寫,直接和ItemService一起保證事務的有效性

 

級聯新增時從表(tb_item_desc),主表(tb_item)

關聯的鍵是itemId

mybatis+mysql底層實現

調用sql

select last_insert_id;

 

商品描述的修改(包括數據回顯和修改過程)

http://manage.jt.com/item/query/item/desc/1474391958

點擊編輯按鈕彈出item-edit頁面,以上一個請求

$.getJSON('/item/query/item/desc/'+data.id,function(_data){

                                        if(_data.status == 200){                                                  itemEditEditor.html(_data.data.itemDesc);

                                        }

        });

第一個參數:'/item/query/item/desc/'+data.id

第二個參數:回調函數function(_data) _data就是SysResult 的json字符串

傳遞給controller的參數是data.id 以restFul形式傳參

 

回顯就是查詢,在itemController和itemService中添加查詢代碼

 

修改部分

修改的前臺js代碼

$.post("/item/update",$("#itemeEditForm").serialize(), function(data){

if(data.status == 200){

$.messager.alert('提示','修改商品成功!','info',function(){

$("#itemEditWindow").window('close');

$("#itemList").datagrid("reload");

});

}

});

/item/update:請求地址

$("#itemeEditForm").serialize():參數將表單內所有標籤封裝成一個模擬的get請求參數

字符串傳遞

function(data):回調函數,data是SysResult的json轉化的js對象

 

商品詳情的刪除工作

 

 

Redis

2018116

15:09

情景討論

在後臺功能已經完成了,

後臺系統的高併發思路:

技術:tomcat集羣+nginx

引入20臺nginx --100萬/s;

考慮一個問題:當100萬個用同時增刪改查操作時;

系統瓶頸在哪:數據庫,尤其是查詢

 

Redis

分佈式,nosql,可以持久化,內存,數據庫

分佈式:數據被劃分

nosql:not only sequence query language

不僅僅支持關係型數據--結構化的數據

還支持非關係型數據--非結構化數據

 

可持久化+內存:啓動回覆機制

數據庫存儲;

可以分佈式的存儲大量海量的數據,存放到內存中,

可以做緩存數據庫

 

京淘中的緩存架構可以如何設計

緩存可以如何添加

 

 

數據庫緩存

執行的過程包括sql,組織查詢結果resultSet

根據sql可以創建緩存,存儲已經查過的resultset,節省了

資源的調度重組resultSet

持久層緩存

減少從數據庫獲取的結果轉化成對象的過程,緩存存在直接調用其中

保存的對象結果;

業務層緩存

減少調用層次

控制層緩存

較少調用層次

 

<問題>可不可以過多使用緩存

緩存是佔用內存空間的,過多的緩存插入,容易造成數據的冗餘

在內存不夠時,清空邏輯會交叉導致數據失效

結論緩存引入的最終目的

1 減少數據庫的訪問壓力

2 減少網絡傳輸

3 減少封裝層次

Redis這個技術就可以在京淘中實現提升性能的目的,緩存

 

介紹緩存

主流的緩存架構

1 ehcache (很多數據庫底層緩存使用ehcache)併發量差

2 memoryCache,10年,高併發的100萬/s; 缺點:不落地

3 Redis:持久化可以在宕機恢復後迅速解決數據丟失

 

<問題>:如果在緩存服務器宕機後,無法進行數據恢復/沒有解決數據重新加載

的問題,會導致“雪崩”/”緩存擊穿“

 

雪崩/緩存擊穿

海量用戶訪問請求湧入,一旦緩存失效(宕機數據丟失);所有的訪問

湧入數據庫;數據庫無法承受海量數據的查詢,導致數據庫服務器宕機;

重啓數據庫,請求查詢沒消失,數據庫--宕機--重啓循環,導致系統崩潰

 

解決雪崩:

1 緩存用不宕機;啓動集羣,永遠讓集羣中的一部分起作用

2 緩存技術必須可以恢復數據,持久化

 

 

安裝redis

2018116

15:47

1 下載安裝包解壓

使用對象存儲的源站地址獲取資源

wget "http://jt-xxw.cn-bj.ufileos.com/redis-3.2.11.tar.gz?UCloudPublicKey=ucloudzhaodong%40tarena.com.cn14442715760002074868321&Signature=5%2Fng5gQ8aUNTTOzY9u%2BEZzmHR8g%3D&Expires=1516091995

"

 

創建管理目錄

[root@10-9-62-65 ~]# cd /home/

[root@10-9-62-65 home]# mkdir software

[root@10-9-62-65 home]# cd software/

[root@10-9-62-65 software]#

使用wget獲取資源

 

解壓

 

redis使用

make && make install

 

 

2 啓動redis

啓動redis的服務

#redis-server

 

使用redis需要啓動redis客戶端

#redis-cli

 

如果想在同一個操作控制檯啓動服務和客戶端

啓動客戶端時可以使用後臺運行命令

#redis-server &

停止redis服務

1 佔用控制檯的redis服務直接ctrl+c停止服務

2 在後臺運行服務的時候,登陸客戶端

shutdown;

 

3 檢查後臺運行的redis服務

ps -ef|grep redis;

 

redis-server 表示redis服務

*:表示能夠訪問當前redis服務的所有ip地址,都可以

如果列出一系列的ip地址,除這些ip意外的所有訪問redis服務的請求

都被拒絕

 

Redis的基礎命令

操作字符串

redis存儲數據是以key-value的形式,key-{key,value},key-list

 

keys:查詢當前的存儲空中的所有存在key;

127.0.0.1:6379> keys *

(empty list or set)

127.0.0.1:6379>

 

set [key名] [value]

設置 key-value值,value是String字符串

127.0.0.1:6379> set name xiao

OK

127.0.0.1:6379> key *

(error) ERR unknown command 'key'

127.0.0.1:6379> keys *

1) "name"

127.0.0.1:6379>

 

get [key名]

獲取key對應的value值

127.0.0.1:6379> keys *

1) "gender"

2) "name"

3) "age"

4) "city"

127.0.0.1:6379> get name

"xiao"

127.0.0.1:6379>

 

select [整數值[0-15]]

redis存在嗎默認的0-15標號的數據分褲,默認使用0號;這個功能是早期

版本冗餘的功能,現在都使用默認0號數據庫;現在java的代碼不支持分庫

127.0.0.1:6379> select 1

OK

127.0.0.1:6379[1]> keys *

(empty list or set)

127.0.0.1:6379[1]>

 

exists [key名]

判斷當前key是否存在;與get的卻別

redis存儲的key-value結構的字符串數據 512M,當邏輯判斷只需要返回是與

否時,get命令獲取的大字符串就佔用了資源的調用

127.0.0.1:6379> exists name

(integer) 1

127.0.0.1:6379> exists xiao

(integer) 0

127.0.0.1:6379>

 

del [key名]

127.0.0.1:6379> del name

(integer) 1

127.0.0.1:6379> keys *

1) "gender"

2) "num"

3) "age"

4) "city"

 

type [key名]

127.0.0.1:6379> set num1 100

OK

127.0.0.1:6379> type num1

string

127.0.0.1:6379>

 

help type/help [命令名稱]

127.0.0.1:6379> help set

  SET key value [EX seconds] [PX milliseconds] [NX|XX]

  summary: Set the string value of a key

  since: 1.0.0

  group: string

127.0.0.1:6379>

實際問題可以到官網查詢對應的命令細節

 

flushall 將所有的當前內存數據(0-15號庫),flush到持久化文件

127.0.0.1:6379> keys *

1) "num1"

2) "gender"

3) "num"

4) "age"

5) "city"

127.0.0.1:6379> flushall

OK

127.0.0.1:6379> keys *

(empty list or set)

 

flushdb flush當前redis某一個標號的庫中的內容到持久化文件

127.0.0.1:6379> keys *

1) "name"

127.0.0.1:6379> selet

(error) ERR unknown command 'selet'

127.0.0.1:6379> selet 1

(error) ERR unknown command 'selet'

127.0.0.1:6379> select 1

OK

127.0.0.1:6379[1]> set name xiao

OK

127.0.0.1:6379[1]> keys *

1) "name"

127.0.0.1:6379[1]> flushdb

OK

127.0.0.1:6379[1]> keys *

(empty list or set)

127.0.0.1:6379[1]> select 0

OK

127.0.0.1:6379> keys *

1) "name"

127.0.0.1:6379>

 

===============================================================================

==========================================================================

DAY06

 

知識回顧

2018117

8:54

1 nginx負載均衡

權重;weight,down關鍵字

session黏着,解決session共享的負載均衡計算方式

ip_hash

 

url_hash,以來第三方插件;

2 商品描述

大字段內容,不破壞商品表的索引,單獨使用一張表來記錄

單獨的desc表數據特別大的時候,分庫,分表保存(早期)

現在幾乎所有的可見查詢功能都使用緩存

完成商品詳情的增刪改查

改和查一體(回顯和修改)

3 Redis介紹

後臺的訪問併發量已經使用nginx+tomcat可以達到很高

程序性能未必能支持如此大的併發量請求

緩存的引入;

分佈式,nosql,可持久化,內存,緩存,數據庫

ehcache,

memoryCache

雪崩:緩存由於各種原因數據丟失,大量請求湧入數據庫,數據庫無法

承受,宕機重啓,緩存沒數據,請求未消失,數據庫繼續宕機,惡性循環

解決雪崩:沒有持久化的功能,必須保證緩存集羣永遠保持部分可使用

在緩存技術中添加持久化,在宕機後可以讀取持久化文件

恢復數據

4 安裝redis+key-value類型數據使用的部分命令

keys*;get,set,exists,flushdb,flushall,type,help,select,del

 

 

 

Redis基礎命令

2018117

9:28

 

incr decr 自增自減

127.0.0.1:6379> set n1 100

OK

127.0.0.1:6379> type n1

string

127.0.0.1:6379> incr n1

(integer) 101

127.0.0.1:6379> get n1

"101"

127.0.0.1:6379> set school bjdx

OK

127.0.0.1:6379> incr school

(error) ERR value is not an integer or out of range

127.0.0.1:6379>

 

incrby 數字 decrby 數字

127.0.0.1:6379> incrby n1 5

(integer) 106

127.0.0.1:6379>

 

append 在value後追加數據

127.0.0.1:6379> set name xiao

OK

127.0.0.1:6379> apend name laoshi

(error) ERR unknown command 'apend'

127.0.0.1:6379> append name laoshi

(integer) 10

127.0.0.1:6379> get name

"xiaolaoshi"

127.0.0.1:6379>

 

mset mget 獲取或者設置一批key-value對

mset k1 v1 k2 v2

mget k1 k2

127.0.0.1:6379> mset n1 100 n2 200 n3 300

OK

127.0.0.1:6379> keys *

1) "name"

2) "n3"

3) "n2"

4) "n1"

127.0.0.1:6379> mget n1 n2 n3

1) "100"

2) "200"

3) "300"

127.0.0.1:6379>

支持的語言API不支持這個命令,這種羣體操作k-v對的過程

無法進行分片和集羣計算;早期redis版本遺留功能;

 

expire [key] 時間數字(單位秒)

設置當前key對應的value的過期時間

ttl 查看當前key-value對的存活時間

127.0.0.1:6379> set bomb c4

OK

127.0.0.1:6379> keys *

1) "name"

2) "n1"

3) "n2"

4) "n3"

5) "bomb"

127.0.0.1:6379> expire bomb 100

(integer) 1

127.0.0.1:6379> ttl

(error) ERR wrong number of arguments for 'ttl' command

127.0.0.1:6379> ttl bomb

(integer) 86

127.0.0.1:6379> ttl bomb

(integer) 85

127.0.0.1:6379> ttl bomb

(integer) 84

127.0.0.1:6379>

第二個案例

127.0.0.1:6379> set bread binbao

OK

127.0.0.1:6379> expire bread 5

(integer) 1

127.0.0.1:6379> ttl bread

(integer) 2

127.0.0.1:6379> ttl bread

(integer) 1

127.0.0.1:6379> ttl bread

(integer) 0

127.0.0.1:6379> ttl bread

(integer) -2

127.0.0.1:6379>

127.0.0.1:6379> ttl name

(integer) -1

127.0.0.1:6379>

-2代表過期,-1代表永久

可以使用數據中的過期來做倒計時

還可以秒殺;

 

pexpire [key] 時間數字(毫秒)

127.0.0.1:6379> pexpire bomb 5000

(integer) 1

127.0.0.1:6379> ttl bomb

(integer) 3

127.0.0.1:6379> ttl bomb

(integer) 2

 

 

 

HASH+LIST

2018117

9:47

1 HASH結構

key-value字符串類型中的key本身也是key-value對兒

 

HSET和HGET賦值和取值

HSET key field value

HGET key field

HMSET key field value [field value…]

HMGET key field value [field value…]

HGETALL key

 

127.0.0.1:6379> hset user username chenchen

(integer) 1

127.0.0.1:6379> hget user username

"chenchen"

127.0.0.1:6379> hset user username chen

(integer) 0

127.0.0.1:6379> keys user

1) "user"

127.0.0.1:6379> hgetall user

1) "username"

2) "chen"

127.0.0.1:6379>

127.0.0.1:6379> hset user age 30

(integer) 1

127.0.0.1:6379> hgetall user

1) "username"

2) "chen"

3) "age"

4) "30"

127.0.0.1:6379>

HSET命令不區分插入和更新操作,當執行插入操作時HSET命令返回1,當執行更新操作時返回0。

HMSET和HMGET設置和獲取對象屬性

127.0.0.1:6379> hmset person username tony age 18

OK

127.0.0.1:6379> hmget person age username

1) "18"

2) "tony"

127.0.0.1:6379> hgetall person

1) "username"

2) "tony"

3) "age"

4) "18"

127.0.0.1:6379>

注意:上面HMGET字段順序可以自行定義

HEXISTS屬性是否存在

127.0.0.1:6379> hexists killer

(error) ERR wrong number of arguments for 'hexists' command

127.0.0.1:6379> hexists killer a

(integer) 0

127.0.0.1:6379> hexists user username

(integer) 1

127.0.0.1:6379> hexists person age

(integer) 1

127.0.0.1:6379>

HDEL刪除對象字段

127.0.0.1:6379> hdel user age

(integer) 1

127.0.0.1:6379> hgetall user

1) "username"

2) "chen"

127.0.0.1:6379> hgetall person

1) "username"

2) "tony"

3) "age"

4) "18"

127.0.0.1:6379>

只獲取字段名HKEYS或字段值HVALS

127.0.0.1:6379> hkeys person

1) "username"

2) "age"

127.0.0.1:6379> hvals person

1) "tony"

2) "18"

獲取字段數量HLEN

127.0.0.1:6379> hlen user

(integer) 1

127.0.0.1:6379> hlen person

(integer) 2

127.0.0.1:6379>

 

List

key-value(雙向鏈表,左-上,右-下)

查看list

redis 127.0.0.1:6379> lrange mylist3 0 -1

lrange key start length

LPUSH

key對應list的頭部添加字符串元素

redis 127.0.0.1:6379> lpush mylist "world"

(integer) 1

redis 127.0.0.1:6379> lpush mylist "hello"

(integer) 2

redis 127.0.0.1:6379> lrange mylist 0 -1

1) "hello"

2) "world"

redis 127.0.0.1:6379>

RPUSH

key對應list的尾部添加字符串元素

redis 127.0.0.1:6379> rpush mylist2 "hello"

(integer) 1

redis 127.0.0.1:6379> rpush mylist2 "world"

(integer) 2

redis 127.0.0.1:6379> lrange mylist2 0 -1

1) "hello"

2) "world"

redis 127.0.0.1:6379>

linsert

key對應list的特定位置之前或之後添加字符串元素

redis 127.0.0.1:6379> rpush mylist3 "hello"

(integer) 1

redis 127.0.0.1:6379> rpush mylist3 "world"

(integer) 2

redis 127.0.0.1:6379> linsert mylist3 before "world" "there"

(integer) 3

redis 127.0.0.1:6379> lrange mylist3 0 -1

1) "hello"

2) "there"

3) "world"

redis 127.0.0.1:6379>

lset

設置list中指定下標的元素值

redis 127.0.0.1:6379> rpush mylist4 "one"

(integer) 1

redis 127.0.0.1:6379> rpush mylist4 "two"

(integer) 2

redis 127.0.0.1:6379> rpush mylist4 "three"

(integer) 3

redis 127.0.0.1:6379> lset mylist4 0 "four"

OK

redis 127.0.0.1:6379> lset mylist4 -2 "five"

OK

redis 127.0.0.1:6379> lrange mylist4 0 -1

1) "four"

2) "five"

3) "three"

redis 127.0.0.1:6379>

大於0是正數

小於0倒數

lrem

key對應list中刪除count個和value相同的元素,count>0時,

按從頭到尾的順序刪除

redis 127.0.0.1:6379> rpush mylist5 "hello"

(integer) 1

redis 127.0.0.1:6379> rpush mylist5 "hello"

(integer) 2

redis 127.0.0.1:6379> rpush mylist5 "foo"

(integer) 3

redis 127.0.0.1:6379> rpush mylist5 "hello"

(integer) 4

redis 127.0.0.1:6379> lrem mylist5 2 "hello"

(integer) 2

redis 127.0.0.1:6379> lrange mylist5 0 -1

1) "foo"

2) "hello"

redis 127.0.0.1:6379>

count<0時,按從尾到頭的順序刪除

redis 127.0.0.1:6379> rpush mylist6 "hello"

(integer) 1

redis 127.0.0.1:6379> rpush mylist6 "hello"

(integer) 2

redis 127.0.0.1:6379> rpush mylist6 "foo"

(integer) 3

redis 127.0.0.1:6379> rpush mylist6 "hello"

(integer) 4

redis 127.0.0.1:6379> lrem mylist6 -2 "hello"

(integer) 2

redis 127.0.0.1:6379> lrange mylist6 0 -1

1) "hello"

2) "foo"

redis 127.0.0.1:6379>

count=0時,刪除全部

redis 127.0.0.1:6379> rpush mylist7 "hello"

(integer) 1

redis 127.0.0.1:6379> rpush mylist7 "hello"

(integer) 2

redis 127.0.0.1:6379> rpush mylist7 "foo"

(integer) 3

redis 127.0.0.1:6379> rpush mylist7 "hello"

(integer) 4

redis 127.0.0.1:6379> lrem mylist7 0 "hello"

(integer) 3

redis 127.0.0.1:6379> lrange mylist7 0 -1

1) "foo"

redis 127.0.0.1:6379>

ltrim

保留指定key 的值範圍內的數據

redis 127.0.0.1:6379> rpush mylist8 "one"

(integer) 1

redis 127.0.0.1:6379> rpush mylist8 "two"

(integer) 2

redis 127.0.0.1:6379> rpush mylist8 "three"

(integer) 3

redis 127.0.0.1:6379> rpush mylist8 "four"

(integer) 4

redis 127.0.0.1:6379> ltrim mylist8 1 -1

OK

redis 127.0.0.1:6379> lrange mylist8 0 -1

1) "two"

2) "three"

3) "four"

redis 127.0.0.1:6379>

lpop

list的頭部刪除元素,並返回刪除元素

redis 127.0.0.1:6379> lrange mylist 0 -1

1) "hello"

2) "world"

redis 127.0.0.1:6379> lpop mylist

"hello"

redis 127.0.0.1:6379> lrange mylist 0 -1

1) "world"

redis 127.0.0.1:6379>

rpop

list的尾部刪除元素,並返回刪除元素:

redis 127.0.0.1:6379> lrange mylist2 0 -1

1) "hello"

2) "world"

redis 127.0.0.1:6379> rpop mylist2

"world"

redis 127.0.0.1:6379> lrange mylist2 0 -1

1) "hello"

redis 127.0.0.1:6379>

rpoplpush

從第一個list的尾部移除元素並添加到第二個list的頭部,最後返回被移除的元素值,整個操作是原子的.如果第一個list是空或者不存在返回nil:

redis 127.0.0.1:6379> lrange mylist5 0 -1

1) "three"

2) "foo"

3) "hello"

redis 127.0.0.1:6379> lrange mylist6 0 -1

1) "hello"

2) "foo"

redis 127.0.0.1:6379> rpoplpush mylist5 mylist6

"hello"

redis 127.0.0.1:6379> lrange mylist5 0 -1

1) "three"

2) "foo"

redis 127.0.0.1:6379> lrange mylist6 0 -1

1) "hello"

2) "hello"

3) "foo"

redis 127.0.0.1:6379>

lindex

返回名稱爲key的list中index位置的元素:

redis 127.0.0.1:6379> lrange mylist5 0 -1

1) "three"

2) "foo"

redis 127.0.0.1:6379> lindex mylist5 0

"three"

redis 127.0.0.1:6379> lindex mylist5 1

"foo"

redis 127.0.0.1:6379>

llen

返回key對應list的長度:

redis 127.0.0.1:6379> llen mylist5

(integer) 2

redis 127.0.0.1:6379>

 

 

 

數據的分佈存儲

2018117

10:44

要完成數據的分片存儲,需要至少多個redis實例

 

啓動多個redis實例

前面的單個redis節點實例的啓動時默認配置

端口號6379

 

配置文件

/redis根目錄/redis.conf

 

配置文件的修改內容

p61 bind 用#註釋掉

 

p80 保護模式不啓動

 

p84 6379是默認端口(要啓動其他的redis實例需要修改端口)

 

p105 當客戶端空閒時間一小時,就會自動斷開連接,0秒錶示

不啓用超時配置

 

p128 daemonize 設置成yes讓redis服務器啓動有守護進程管理

(後臺執行)

 

p150 對應不同的redis實例,pid的文件名稱需要和端口同名

 

save 900(秒) 1(變動的數據條數)

當900以內,至少有1條數據變動,看是flush保存數據到文件

save 300 10

300秒以內至少10條數據變動,保存文件

save 60 10000

 

 

啓動第二和第三個redis實例

redis-server redis.conf(指定啓動文件)

需要第二個實例的配置文件

需要第三個實例的配置文件

拷貝redis.conf,用redis6380.conf,redis6381.conf

 

將拷貝的文件中只修改與端口有關內容

port

 

pid文件

 

6381的略

 

啓動另外兩個節點

#redis-server redis6380.conf

#redis-server redis6381.conf

#ps -ef|grep redis

 

 

指定端口登錄客戶端redis-cli -p [端口號]

#redis-cli -p 6380

 

#redis-cli -p 6381

 

 

6380和6381會共享6379dump.db文件

所以不同的節點實例在同一個機器上運行時,可以修改dump.db

指定端口文件;

 

三個節點,怎麼分佈式保存數據?

數據來源:代碼的邏輯執行

如何使用代碼來操作redis執行分佈式的數據存儲過程?

引出了Jedis客戶端

 

 

 

Jedis

2018117

11:36

測試jedis控制redis的命令功能

需要導入jedis包

 

 

自定義分片

準備數據:

葵花寶典A,B,C三部分數據

將三部分數據分別存儲到redis 6379 6380 6381

 

哈希取餘

利用hash的散列特性,可以處理海量非結構化數據的散列分佈的分片計算

代碼

 

jedis分片

沒有在分片時使用哈希取餘,hash一致性

 

經過代碼發現,一般的自定義分片邏輯計算無法做到散列

不散列無法均衡

 

jedis池

 

 

 

 

HASH一致性

2018117

15:27

作爲散列算法

考慮哈西取餘的問題

1 容易產生大規模的數據傾斜(散列必定傾斜)

hash一致性一定程度的解決了數據傾斜;

2 哈希取餘算法,導致數據遷移量過大

 

redis集羣數量進行增加減少的時候,哈希取餘算法中的n變化了

由於n的變化,數據命中變化量非常大,需要遷移的數據量非常大,

 

jedis中引入另外一種hash散列算法--hash一致性

1997麻省理工學生髮明;引入一個2^32-1(43億)整數環,

把節點使用ip+端口做哈希散列計算,得到43億中一個值,投射到環中

將所有的數據key進行哈希散列計算,得到43億中的一個

 

node1,2,3個節點啓動着redis

數據分別是key1,2,3,4

根據hash散列算法都投射到一個整數上

順時針尋找最近節點的映射規則,將key值進行存放

key1,2存儲在node1

key3存儲在node2

key4存儲在node3

 

當增加刪除節點時,遷移量有何變化?

 

增加node4,根據散列得到43億中一個整數,投射到環上

根據順時針尋找最近節點存儲的原則,只需要遷移key4

而且可以判斷,原節點數量越多,遷移量越小

 

節點刪除,將node2刪除,遷移key3

 

 

解決數據平衡性

單獨的使用節點的ip+端口做映射,畢竟節點數量是有限的

有可能在映射時的各自分佈位置並不平均,導致數據偏移量非常大

 

解決數據的平衡性引入虛擬節點

node1的ip是192.168.40.156

node2的ip是192.168.40.157

各自引入2個虛擬節點(虛擬節點的數量是非常大的)

node1-1=hash(192.168.40.156#1)

node1-2=hash(192.168.40.156#2)

node2-1=hash(192.168.40.157#1)

node2-2=hash(192.168.40.157#2)

每一個虛擬節點在哈希環上也會接收順時針尋找最近節點的key們

通過增加節點數量(虛擬的),完成數據的映射平衡

凡是投影到node1-1,node1-2的key,都會中真實存儲在node1中

所以虛擬節點越多平衡性越好

 

 

 

京淘的緩存引入

2018117

16:24

根據在模擬緩存的邏輯,思考後臺什麼位置可以做緩存?

商品分類樹(緩存版本1)

商品列表(不好做,有分頁參數)

商品新增,修改,刪除

商品詳情新增,修改,刪除

 

 

補充內容

2018117

10:19

HASH取餘數據分片

 

 

原子級操作

一系列操作如果稱之爲原子級,不可分割,一旦分隔開

系列操作不成功

 

 

 

當天問題

2018117

16:51

 

版本1的緩存引入京淘時

商品分類樹查詢

Name [spring.liveBeansView.mbeanDomain] is not bound in this Context. Unable to find [spring.liveBeansView.mbeanDomain].. Returning null.

 

原因,從mysql查詢的數據沒有text,state

返回json需要text和state,ItemCat類中的兩個get方法,導致MAPPER轉化字符串和對象時的錯誤

在ItemCat中添加一個註解,讓MAPPER轉化時忽略這兩個屬性


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章