大数据 互联网架构阶段 Redis
生活随笔
收集整理的這篇文章主要介紹了
大数据 互联网架构阶段 Redis
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
Redis
零、 目錄
- 高并發(fā)思路
- 電商網(wǎng)站中緩存數(shù)據(jù)庫的設(shè)計
- 緩存介紹
- 按照redis
- redis常用命令
- redis其他數(shù)據(jù)結(jié)構(gòu)
- 數(shù)據(jù)分布式存儲
- Jedis客戶端
- 哈希一致性
- 補(bǔ)充
一、 高并發(fā)思路
二、 電商網(wǎng)站中緩存數(shù)據(jù)庫如何設(shè)計
三、緩存介紹
1. 雪崩(緩存擊穿): 海量用戶訪問請求涌入 , 一旦緩存失效(宕機(jī)后緩存數(shù)據(jù)丟失) , 所有訪問涌入數(shù)據(jù)庫 , 數(shù)據(jù)庫無法承受海量的數(shù)據(jù)的查詢 , 導(dǎo)致數(shù)據(jù)庫服務(wù)器宕機(jī) , 這時重啟數(shù)據(jù)庫 , 但是請求沒有消失甚至用戶在不斷的刷新(請求瞬間翻倍) , 就發(fā)生了數(shù)據(jù)庫在重啟->宕機(jī)->重啟中循環(huán) , 導(dǎo)致整個系統(tǒng)崩潰。
四、 安裝redis
下載安裝包并解壓
下載命令wget "http://bj-yzjd.cn-bj.ufileos.com/redis-3.2.11.tar.gz" 解壓tar -xvf redis-3.2.11.tar.gz進(jìn)入解壓之后的文件 , 執(zhí)行安裝
make && make install啟動redis
redis-server則啟動成功
使用redis
使用redis需要啟動redis客戶端
redis-cli如果想在同一個連接中啟動服務(wù)和客戶端 , 則啟動redis時可以使redis服務(wù)器在后臺運(yùn)行
redis-server &停止redis服務(wù)
在客戶端中
shutdown檢查后臺 運(yùn)行的 redis
ps -ef|grep redis五、 redis常用命令
六、 redis其他數(shù)據(jù)結(jié)構(gòu)
七、 數(shù)據(jù)分布式存儲
八、 Jedis客戶端
在使用之前需要先導(dǎo)入Jedis的jar包
<jedis.version>2.6.0</jedis.version><!-- jedis --> <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>${jedis.version}</version> </dependency>Jedis示例:
/*** 測試單個結(jié)點(diǎn)(單個redis)連接* */@Testpublic void test_01() {//創(chuàng)建Jedis對象 , 并在構(gòu)造方法中設(shè)置redis主機(jī)的ip和占用的端口Jedis jedis = new Jedis("106.75.48.3",6379);//使用Jedis進(jìn)行簡單的操作//存數(shù)據(jù)jedis.set("name", "tianjie");//取數(shù)據(jù)String name = jedis.get("name");System.out.println("name="+name);} /*** 模擬數(shù)據(jù)緩存執(zhí)行邏輯 , 數(shù)據(jù)庫的查詢操作* */ @Test public void test_02() {System.out.println("用戶開始查詢數(shù)據(jù)");//模擬客戶端傳來的參數(shù)String name = "name";//創(chuàng)建一個Jedis客戶端Jedis jedis = new Jedis("106.75.48.3" , 6379);//執(zhí)行邏輯 //1. 先查詢緩存中是否有數(shù)據(jù) , 如果有則返回緩存中的數(shù)據(jù)//2. 如果緩存中沒有數(shù)據(jù)則去數(shù)據(jù)庫中查詢數(shù)據(jù) , 并且 把查詢到的數(shù)據(jù)存入緩存中 , 供后續(xù)使用 , 返回數(shù)據(jù)庫中查詢到的信息String gname = jedis.get("name");if(gname != null && !gname.equals("")) {//緩存中有數(shù)據(jù)System.out.println("從緩存中獲取到的數(shù)據(jù)為:name = "+gname);}else {//緩存中沒有數(shù)據(jù)//執(zhí)行從數(shù)據(jù)庫查詢數(shù)據(jù) 略String dbname = "outman";//數(shù)據(jù)庫查詢到的數(shù)據(jù)//將查詢到的數(shù)據(jù)存入緩存中 jedis.set("name", dbname);//返回從數(shù)據(jù)庫中查到的數(shù)據(jù)System.out.println("從數(shù)據(jù)庫獲取到的數(shù)據(jù)為:name = "+dbname);}//第一次執(zhí)行結(jié)果為從數(shù)據(jù)庫中獲取//第二次執(zhí)行結(jié)果我從緩存中獲取數(shù)據(jù) }自定義分片算法 ,將數(shù)據(jù)分片存入多個redis實(shí)例
/*** 自定義分片計算邏輯* */@Testpublic void test_03() {//模擬需要存儲的數(shù)據(jù)String k1 = "四十二章經(jīng)第一章";String v1 = "111111111111111111";String k2 = "四十二章經(jīng)第二章";String v2 = "222222222222222222";String k3 = "四十二章經(jīng)第三章";String v3 = "333333333333333333";List<String> keyList = new ArrayList<String >();keyList.add(k1);keyList.add(k2);keyList.add(k3);Map<String , String > map = new HashMap<String , String >();map.put(k1, v1);map.put(k2, v2);map.put(k3, v3);for(String key : keyList) {if("四十二章經(jīng)第一章".equals(key)) {//存入第一個redis結(jié)點(diǎn)Jedis jedis = new Jedis("106.75.48.3" , 6379);jedis.set(key, map.get(key));}else if("四十二章經(jīng)第二章".equals(key)) {//存入第二個redis結(jié)點(diǎn)Jedis jedis = new Jedis("106.75.48.3" , 6380);jedis.set(key, map.get(key));}else if("四十二章經(jīng)第三章".equals(key)) {//存入第三個redis結(jié)點(diǎn)Jedis jedis = new Jedis("106.75.48.3" , 6381);jedis.set(key, map.get(key));}}}使用hash取余法將數(shù)據(jù)分片存儲
/*** 哈希取余分片存儲邏輯* */@Testpublic void test_04() {//模擬需要被存儲的數(shù)據(jù)List<String> keyList = new ArrayList<String>();Map<String , String> map = new HashMap<String, String>();for(int i = 0 ; i<100 ; i++) {String key = "key_"+i;String value = "value_"+i;keyList.add(key);map.put(key, value);}//使用哈希取余法分片存儲//定義結(jié)點(diǎn)(redis實(shí)例)數(shù)量int n = 3;for(String key : keyList) {//執(zhí)行哈希取余 , 哈希結(jié)果可能為負(fù)數(shù) , 此時需要與Integer的最大數(shù)進(jìn)行與操作Integer num =( key.hashCode()&Integer.MAX_VALUE )%n; if(num == 0) {//存入第一個結(jié)點(diǎn)Jedis jedis = new Jedis("106.75.48.3" , 6379);jedis.set(key, map.get(key));jedis.close();}else if(num == 1) {//存入第二個結(jié)點(diǎn)Jedis jedis = new Jedis("106.75.48.3" , 6380);jedis.set(key, map.get(key));jedis.close();}else if(num == 2) {//存入第三個結(jié)點(diǎn)Jedis jedis = new Jedis("106.75.48.3" , 6381);jedis.set(key, map.get(key));jedis.close();}}//執(zhí)行結(jié)果 100個鍵值對幾乎均勻的 分布存儲在三臺redis實(shí)例上}jedis分片 , 使用的hash一致性
/*** Jedis分片 使用哈希一致型完成數(shù)據(jù)分片存儲(Jedis默認(rèn)的分片算法)* */@Testpublic void test_05() {//需要構(gòu)造存儲多個reids實(shí)例信息 的listList<JedisShardInfo> jedisList = new ArrayList<JedisShardInfo>();//創(chuàng)建結(jié)點(diǎn)信息JedisShardInfo info1 = new JedisShardInfo("106.75.48.3" , 6379);JedisShardInfo info2 = new JedisShardInfo("106.75.48.3" , 6380);JedisShardInfo info3 = new JedisShardInfo("106.75.48.3" , 6381);//list保存結(jié)點(diǎn)信息jedisList.add(info1);jedisList.add(info2);jedisList.add(info3);//構(gòu)造一個Jedis分片對象 , 將list闖入構(gòu)造方法中 , 狗后續(xù)分片ShardedJedis jedis = new ShardedJedis(jedisList);//模擬海量數(shù)據(jù)執(zhí)行數(shù)據(jù)分片存儲for( int i= 0 ; i<1000 ; i++) {jedis.set("key_"+i, "value_" + i);}jedis.close();//數(shù)據(jù)通過哈希一致型算法分片存儲在了多個reids實(shí)例中//單數(shù)每一個reids的實(shí)例的數(shù)據(jù)量并不是完全平均的 , 會有一定量的數(shù)據(jù)偏移}jedis池的使用
/*** Jedis池* */@Testpublic void test_06() {//需要構(gòu)造存儲多個reids實(shí)例信息 的listList<JedisShardInfo> jedisList = new ArrayList<JedisShardInfo>();//創(chuàng)建結(jié)點(diǎn)信息JedisShardInfo info1 = new JedisShardInfo("106.75.48.3" , 6379);JedisShardInfo info2 = new JedisShardInfo("106.75.48.3" , 6380);JedisShardInfo info3 = new JedisShardInfo("106.75.48.3" , 6381);//list保存結(jié)點(diǎn)信息jedisList.add(info1);jedisList.add(info2);jedisList.add(info3);//對于連接來將 類似于JDBC連接處可以設(shè)置很多參數(shù)JedisPoolConfig config = new JedisPoolConfig();//設(shè)置最大連接數(shù)config.setMaxTotal(200);//創(chuàng)建Jeids連接池ShardedJedisPool pool = new ShardedJedisPool(config, jedisList);//使用連接處獲取數(shù)據(jù)ShardedJedis jedis = pool.getResource();for(int i = 0 ; i<100 ; i++) {String value = jedis.get("key_"+i);System.out.println("獲取到key_"+i+"的值為"+value);}//歸還連接pool.returnResource(jedis);}九、哈希一致性
哈希一致型
解決數(shù)據(jù)偏移問題
有可能在映射時的各自分布位置并不平均,導(dǎo)致數(shù)據(jù)偏移量非常大
解決數(shù)據(jù)的平衡性引入虛擬節(jié)點(diǎn) node1的ip是192.168.40.156 node2的ip是192.168.40.157 各自引入2個虛擬節(jié)點(diǎn)(虛擬節(jié)點(diǎn)的數(shù)量是非常大的) 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) 每一個虛擬節(jié)點(diǎn)在哈希環(huán)上也會接收順時針尋找最近節(jié)點(diǎn)的key們 通過增加節(jié)點(diǎn)數(shù)量(虛擬的),完成數(shù)據(jù)的映射平衡 凡是投影到node1-1,node1-2的key,都會中真實(shí)存儲在node1中 所以虛擬節(jié)點(diǎn)越多平衡性越好補(bǔ)充:
總結(jié)
以上是生活随笔為你收集整理的大数据 互联网架构阶段 Redis的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大数据 互联网架构阶段 电商项目简介
- 下一篇: 大数据互联网架构阶段 Redis(二)