redis學習資料及架構(gòu)部署

0. NoSQL 產(chǎn)品(key-value)

RDBMS :MySQL合呐,Oracle ,MSSQL,PGNoSQL:Redis,MongoDB,列存儲存儲相關(guān)NewSQL----->分布式數(shù)據(jù)庫架構(gòu)(學習了MongoDB)緩存產(chǎn)品介紹:memcached (大公司會做二次開發(fā))redisTair

1. Redis功能介紹

數(shù)據(jù)類型豐富? ? (筆試漠嵌、面試)*****支持持久化? ? ? (筆試、面試) *****多種內(nèi)存分配及回收策略支持事務? ? ? ? ? ? (面試)? ? ****消息隊列盖呼、消息訂閱 支持高可用? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ****支持分布式分片集群 (面試)? *****緩存穿透\雪崩(筆試儒鹿、面試)? *****Redis API? ? ? ? ? ? ? ? ? **

2、企業(yè)緩存產(chǎn)品介紹

Memcached:優(yōu)點:高性能讀寫几晤、單一數(shù)據(jù)類型绕娘、支持客戶端式分布式集群碎罚、一致性hash多核結(jié)構(gòu)、多線程讀寫性能高。缺點:無持久化横蜒、節(jié)點故障可能出現(xiàn)緩存穿透、分布式需要客戶端實現(xiàn)贫贝、跨機房數(shù)據(jù)同步困難热幔、架構(gòu)擴容復雜度高Redis:? 優(yōu)點:高性能讀寫、多數(shù)據(jù)類型支持众雷、數(shù)據(jù)持久化灸拍、高可用架構(gòu)、支持自定義虛擬內(nèi)存砾省、支持分布式分片集群鸡岗、單線程讀寫性能極高缺點:多線程讀寫較Memcached慢新浪、京東编兄、直播類平臺轩性、網(wǎng)頁游戲? ? memcache與redis在讀寫性能的對比memcached 適合,多用戶訪問,每個用戶少量的rwredis? ? 適合,少用戶訪問,每個用戶大量rw? ? ? ? ? ? Tair:優(yōu)點:高性能讀寫、支持三種存儲引擎(ddb狠鸳、rdb揣苏、ldb)、支持高可用碰煌、支持分布式分片集群舒岸、支撐了幾乎所有淘寶業(yè)務的緩存。? ? 缺點:單機情況下芦圾,讀寫性能較其他兩種產(chǎn)品較慢

3蛾派、Redis使用場景介紹

Memcached:多核的緩存服務,更加適合于多用戶并發(fā)訪問次數(shù)較少的應用場景Redis:單核的緩存服務,單節(jié)點情況下洪乍,更加適合于少量用戶眯杏,多次訪問的應用場景。Redis一般是單機多實例架構(gòu)壳澳,配合redis集群出現(xiàn)岂贩。

4、Redis安裝部署:

下載:wget http://download.redis.io/releases/redis-3.2.12.tar.gz解壓:上傳至/datatar xzf redis-3.2.12.tar.gzmv redis-3.2.12redis安裝:yum-y install gcc automake autoconf libtool makecd redismake環(huán)境變量:vim/etc/profileexportPATH=/data/redis/src:$PATHsource/etc/profile 啟動:redis-server&連接測試:redis-cli127.0.0.1:6379>setnum10OK127.0.0.1:6379>getnum10

5巷波、Redis基本管理操作

5.1基礎(chǔ)配置文件介紹

mkdir/data/6379cat>/data/6379/redis.conf<<EOFdaemonize yesport6379logfile/data/6379/redis.logdir/data/6379dbfilename dump.rdbEOFredis-cli shutdown redis-server/data/6379/redis.conf netstat-lnp|grep63+++++++++++配置文件說明++++++++++++++redis.conf是否后臺運行:daemonize yes默認端口:port6379日志文件位置logfile/var/log/redis.log持久化文件存儲位置dir/data/6379RDB持久化數(shù)據(jù)文件:dbfilename dump.rdb++++++++++++++++++++++++++++++++++++++redis-cli127.0.0.1:6379>setname zhangsan OK127.0.0.1:6379>getname"zhangsan"

5.2 redis安全配置

redis默認開啟了保護模式萎津,只允許本地回環(huán)地址登錄并訪問數(shù)據(jù)庫。禁止protected-modeprotected-mode yes/no (保護模式抹镊,是否只允許本地訪問)(1)Bind:指定IP進行監(jiān)聽vim/data/6379/redis.confbind10.0.0.51127.0.0.1(2)增加requirepass{password}vim/data/6379/redis.confrequirepass123456----------驗證-----方法一:[root@db03~]# redis-cli -a 123456127.0.0.1:6379>set name zhangsanOK127.0.0.1:6379>exit方法二:[root@db03~]# redis-cli127.0.0.1:6379>auth123456OK127.0.0.1:6379>set a b[root@db01src]# redis-cli -a 123 -h 10.0.0.51 -p 637910.0.0.51:6379>set b2OK

5.3 在線查看和修改配置

CONFIG GET *CONFIG GET requirepassCONFIG GET r*CONFIG SET requirepass 123

5.4 redis持久化(內(nèi)存數(shù)據(jù)保存到磁盤)

RDB锉屈、AOFRDB 持久化? ? 可以在指定的時間間隔內(nèi)生成數(shù)據(jù)集的 時間點快照(point-in-time snapshot)。? ? 優(yōu)點:速度快垮耳,適合于用做備份颈渊,主從復制也是基于RDB持久化功能實現(xiàn)的。? ? 缺點:會有數(shù)據(jù)丟失rdb持久化核心配置參數(shù):vim/data/6379/redis.confdir/data/6379dbfilename dump.rdbsave9001save30010save6010000配置分別表示:900秒(15分鐘)內(nèi)有1個更改300秒(5分鐘)內(nèi)有10個更改60秒內(nèi)有10000個更改? AOF 持久化(append-only log file)記錄服務器執(zhí)行的所有寫操作命令终佛,并在服務器啟動時俊嗽,通過重新執(zhí)行這些命令來還原數(shù)據(jù)集。? ? AOF 文件中的命令全部以 Redis 協(xié)議的格式來保存铃彰,新命令會被追加到文件的末尾绍豁。? ? 優(yōu)點:可以最大程度保證數(shù)據(jù)不丟? ? 缺點:日志記錄量級比較大AOF持久化配置appendonly yesappendfsync alwaysappendfsync everysecappendfsync no是否打開aof日志功能每1個命令,都立即同步到aof 每秒寫1次寫入工作交給操作系統(tǒng),由操作系統(tǒng)判斷緩沖區(qū)大小,統(tǒng)一寫入到aof.vim/data/6379/redis.confappendonly yesappendfsync everysec 面試: redis 持久化方式有哪些?有什么區(qū)別豌研?rdb:基于快照的持久化妹田,速度更快,一般用作備份鹃共,主從復制也是依賴于rdb持久化功能aof:以追加的方式記錄redis操作日志的文件∈还埃可以最大程度的保證redis數(shù)據(jù)安全霜浴,類似于mysql的binlog

6、Redis數(shù)據(jù)類型(筆試):

##6.1介紹String :? ? ? 字符類型Hash:? ? ? ? 字典類型List:? ? ? ? 列表? ? Set:? ? ? ? ? 集合 Sortedset:? 有序集合

image.png

6.2 KEY的通用操作

KEYS *? keys a? keys a*? ? 查看已存在所有鍵的名字? ****TYPE? ? ? ? ? ? ? ? ? ? ? ? 返回鍵所存儲值的類型? ? ****EXPIRE\ PEXPIRE? ? ? ? ? ? 以秒\毫秒設(shè)定生存時間? ? ? ***TTL\ PTTL? ? ? ? ? ? ? ? ? 以秒\毫秒為單位返回生存時間 ***PERSIST? ? ? ? ? ? ? ? ? ? 取消生存時間設(shè)置? ? ? ? ? ? ***DEL? ? ? ? ? ? ? ? ? ? ? ? 刪除一個keyEXISTS? ? ? ? ? ? ? ? ? ? ? 檢查是否存在RENAME? ? ? ? ? ? ? ? ? ? ? 變更KEY名---例子:127.0.0.1:6379> set name zhangsan 127.0.0.1:6379> EXPIRE name 60(integer)1127.0.0.1:6379> ttl name(integer)57127.0.0.1:6379> set a b ex 60OK127.0.0.1:6379> ttl a127.0.0.1:6379> PERSIST a(integer)1127.0.0.1:6379> ttl a(integer)-1

6.3 Strings

應用場景session 共享常規(guī)計數(shù):微博數(shù)蓝纲,粉絲數(shù)阴孟,訂閱、禮物key:value----------(1) set name zhangsan? (2) MSET id 101 name zhangsan age 20 gender m 等價于以下操作: SET id 101? set name zhangsan? set age 20? set gender m(3)計數(shù)器每點一次關(guān)注税迷,都執(zhí)行以下命令一次127.0.0.1:6379> incr num顯示粉絲數(shù)量:127.0.0.1:6379> get num暗箱操作:127.0.0.1:6379> INCRBY num 10000(integer)10006127.0.0.1:6379> get num"10006"127.0.0.1:6379> DECRBY num 10000(integer)6127.0.0.1:6379> get num"6"詳細的例子:------------------------------------增set mykey"test"為鍵設(shè)置新值永丝,并覆蓋原有值getset mycounter 0? ? ? ? ? ? ? 設(shè)置值,取值同時進行setex mykey 10"hello"設(shè)置指定 Key 的過期時間為10秒,在存活時間可以獲取valuesetnx mykey"hello"若該鍵不存在,則為鍵設(shè)置新值mset key3"zyx"key4"xyz"批量設(shè)置鍵刪del mykey? ? ? ? ? ? ? ? ? ? ? ? 刪除已有鍵改append mykey"hello"若該鍵并不存在,返回當前 Value 的長度? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 該鍵已經(jīng)存在箭养,返回追加后 Value的長度incr mykey? ? ? ? ? ? ? ? ? ? ? 值增加1,若該key不存在,創(chuàng)建key,初始值設(shè)為0,增加后結(jié)果為1decrby? mykey? 5? ? ? ? ? ? ? ? 值減少5setrange mykey 20 dd? ? ? ? ? ? 把第21和22個字節(jié),替換為dd,超過value長度,自動補0查? exists mykey? ? ? ? ? ? ? ? ? ? 判斷該鍵是否存在慕嚷,存在返回 1,否則返回0get mykey? ? ? ? ? ? ? ? ? ? ? 獲取Key對應的valuestrlen mykey? ? ? ? ? ? ? ? ? ? 獲取指定 Key 的字符長度ttl mykey? ? ? ? ? ? ? ? ? ? ? 查看一下指定 Key 的剩余存活時間(秒數(shù))getrange mykey 1 20? ? ? ? ? ? 獲取第2到第20個字節(jié),若20超過value長度,則截取第2個和后面所有的mget key3 key4? ? ? ? ? ? ? ? ? 批量獲取鍵

6.4 hash類型(字典類型)

應用場景:存儲部分變更的數(shù)據(jù),如用戶信息等喝检。最接近mysql表結(jié)構(gòu)的一種類型主要是可以做數(shù)據(jù)庫緩存嗅辣。存數(shù)據(jù):hmset stu? id101name zhangsan age20gender mhmset stu1 id102name zhangsan1 age21gender f取數(shù)據(jù):HMGETstu id name age genderHMGETstu1 id name age genderselectconcat("hmset city_",id," id ",id," name ",name," countrycode ",countrycode," district ",district," population ",population)fromcity limit10intooutfile'/tmp/hmset.txt'---------------------更多的例子增hset myhash field1"s"若字段field1不存在,創(chuàng)建該鍵及與其關(guān)聯(lián)的Hashes,Hashes中,key為field1,并設(shè)value為s ,若存在會覆蓋原valuehsetnx myhash field1 s? ? 若字段field1不存在,創(chuàng)建該鍵及與其關(guān)聯(lián)的Hashes,Hashes中,key為field1,并設(shè)value為s挠说, 若字段field1存在,則無效hmset myhash field1"hello"field2 "world? ? ? 一次性設(shè)置多個字段刪hdel myhash field1? ? ? ? ? ? ? ? ? ? ? 刪除 myhash 鍵中字段名為 field1 的字段del myhash? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 刪除鍵改? hincrby myhash field1給field的值加1查hget myhash field1? ? ? ? ? ? ? ? ? ? ? 獲取鍵值為 myhash,字段為 field1 的值hlen myhash? ? ? ? ? ? ? ? ? ? ? ? ? ? 獲取myhash鍵的字段數(shù)量hexists myhash field1? ? ? ? ? ? ? ? ? 判斷 myhash 鍵中是否存在字段名為 field1 的字段hmget myhash field1 field2 field3? ? ? 一次性獲取多個字段hgetall myhash? ? ? ? ? ? ? ? ? ? ? ? ? 返回 myhash 鍵的所有字段及其值hkeys myhash? ? ? ? ? ? ? ? ? ? ? ? ? ? 獲取myhash 鍵中所有字段的名字hvals myhash? ? ? ? ? ? ? ? ? ? ? ? ? ? 獲取 myhash 鍵中所有字段的值

6.5 LIST(列表)

應用場景消息隊列系統(tǒng)比如sina微博在Redis中我們的最新微博ID使用了常駐緩存澡谭,這是一直更新的。但是做了限制不能超過5000個ID损俭,因此獲取ID的函數(shù)會一直詢問Redis蛙奖。只有在start/count參數(shù)超出了這個范圍的時候,才需要去訪問數(shù)據(jù)庫杆兵。系統(tǒng)不會像傳統(tǒng)方式那樣“刷新”緩存雁仲,Redis實例中的信息永遠是一致的。SQL數(shù)據(jù)庫(或是硬盤上的其他類型數(shù)據(jù)庫)只是在用戶需要獲取“很遠”的數(shù)據(jù)時才會被觸發(fā)拧咳,而主頁或第一個評論頁是不會麻煩到硬盤上的數(shù)據(jù)庫了伯顶。微信朋友圈:127.0.0.1:6379>LPUSHwechat"today is nice day !"127.0.0.1:6379>LPUSHwechat"today is bad day !"127.0.0.1:6379>LPUSHwechat"today is good? day !"127.0.0.1:6379>LPUSHwechat"today is rainy? day !"127.0.0.1:6379>LPUSHwechat"today is friday !"[5,4,3,2,1]01234[e,d,c,b,a]01234127.0.0.1:6379>lrange wechat001)"today is friday !"127.0.0.1:6379>lrange wechat011)"today is friday !"2)"today is rainy? day !"127.0.0.1:6379>lrange wechat021)"today is friday !"2)"today is rainy? day !"3)"today is good? day !"127.0.0.1:6379>lrange wechat03127.0.0.1:6379>lrange wechat-2-11)"today is bad day !"2)"today is nice day !"-----------------增 lpush mykey a b? ? ? ? ? ? 若key不存在,創(chuàng)建該鍵及與其關(guān)聯(lián)的List,依次插入a,b, 若List類型的key存在,則插入value中l(wèi)pushx mykey2 e? ? ? ? ? ? 若key不存在,此命令無效骆膝, 若key存在,則插入value中l(wèi)insert mykey before a a1? 在 a 的前面插入新元素 a1linsert mykey after e e2? ? 在e 的后面插入新元素 e2rpush mykey a b? ? ? ? ? ? 在鏈表尾部先插入b,在插入arpushx mykey e? ? ? ? ? ? ? 若key存在,在尾部插入e,若key不存在,則無效rpoplpush mykey mykey2? ? ? 將mykey的尾部元素彈出,再插入到mykey2 的頭部(原子性的操作)刪del mykey? ? ? ? ? ? ? ? ? 刪除已有鍵 lrem mykey2a? ? ? ? ? ? ? 從頭部開始找,按先后順序,值為a的元素,刪除數(shù)量為2個,若存在第3個,則不刪除ltrim mykey02從頭開始,索引為0,1,2的3個元素,其余全部刪除改lset mykey1e? ? ? ? ? ? ? 從頭開始,將索引為1的元素值,設(shè)置為新值 e,若索引越界,則返回錯誤信息rpoplpush mykey mykey? ? ? 將 mykey 中的尾部元素移到其頭部查lrange mykey0-1取鏈表中的全部元素祭衩,其中0表示第一個元素,-1表示最后一個元素。lrange mykey02從頭開始,取索引為0,1,2的元素lrange mykey00從頭開始,取第一個元素,從第0個開始,到第0個結(jié)束lpop mykey? ? ? ? ? ? ? ? ? 獲取頭部元素,并且彈出頭部元素,出棧lindex mykey6從頭開始,獲取索引為6的元素 若下標越界,則返回nil

6.6 SET 集合類型(join union)

應用場景:案例:在微博應用中阅签,可以將一個用戶所有的關(guān)注人存在一個集合中掐暮,將其所有粉絲存在一個集合。Redis還為集合提供了求交集政钟、并集路克、差集等操作,可以非常方便的實現(xiàn)如共同關(guān)注养交、共同喜好精算、二度好友等功能,對上面的所有集合操作碎连,你還可以使用不同的命令選擇將結(jié)果返回給客戶端還是存集到一個新的集合中灰羽。127.0.0.1:6379> sadd lxl pg1 jnl baoqiang gsy alexsb(integer)5127.0.0.1:6379> sadd jnl baoqiang ms bbh yf wxg(integer)5127.0.0.1:6379> SUNION lx jnl1)"baoqiang"2)"yf"3)"bbh"4)"ms"5)"wxg"127.0.0.1:6379> SUNION lxl? jnl1)"gsy"2)"yf"3)"alexsb"4)"bbh"5)"jnl"6)"pg1"7)"baoqiang"8)"ms"9)"wxg"127.0.0.1:6379> 127.0.0.1:6379> 127.0.0.1:6379> 127.0.0.1:6379> 127.0.0.1:6379> SINTER lxl jnl1)"baoqiang"127.0.0.1:6379> 127.0.0.1:6379> 127.0.0.1:6379> 127.0.0.1:6379> 127.0.0.1:6379> 127.0.0.1:6379> 127.0.0.1:6379> SDIFF jnl lxl1)"wxg"2)"yf"3)"bbh"4)"ms"127.0.0.1:6379> 127.0.0.1:6379> 127.0.0.1:6379> 127.0.0.1:6379> 127.0.0.1:6379> SDIFF lxl jnl1)"jnl"2)"pg1"3)"gsy"4)"alexsb"增sadd myset a b c? 若key不存在,創(chuàng)建該鍵及與其關(guān)聯(lián)的set,依次插入a,b,若key存在,則插入value中,若a 在myset中已經(jīng)存在,則插入了 d 和 e 兩個新成員。刪spop myset? ? ? ? ? ? ? 尾部的b被移出,事實上b并不是之前插入的第一個或最后一個成員srem myset a d f? ? ? ? 若f不存在,移出 a鱼辙、d,并返回2改smove myset myset2 a? ? ? ? 將a從 myset 移到 myset2廉嚼,查sismember myset a? ? ? ? ? 判斷 a 是否已經(jīng)存在,返回值為 1 表示存在倒戏。smembers myset? ? ? ? ? 查看set中的內(nèi)容scard myset? ? ? ? ? ? 獲取Set 集合中元素的數(shù)量srandmember myset? ? ? 隨機的返回某一成員sdiff myset1 myset2 myset3? ? ? 1和2得到一個結(jié)果,拿這個集合和3比較,獲得每個獨有的值sdiffstore diffkey myset myset2 myset3? ? ? 3個集和比較,獲取獨有的元素,并存入diffkey 關(guān)聯(lián)的Set中sinter myset myset2 myset3? ? ? ? ? ? ? 獲得3個集合中都有的元素sinterstore interkey myset myset2 myset3? 把交集存入interkey 關(guān)聯(lián)的Set中sunion myset myset2 myset3? ? ? ? ? ? ? 獲取3個集合中的成員的并集sunionstore unionkey myset myset2 myset3? 把并集存入unionkey 關(guān)聯(lián)的Set中

6.7 SortedSet(有序集合)

應用場景:排行榜應用怠噪,取TOPN操作這個需求與上面需求的不同之處在于,前面操作以時間為權(quán)重杜跷,這個是以某個條件為權(quán)重傍念,比如按頂?shù)拇螖?shù)排序矫夷,這時候就需要我們的sorted set出馬了,將你要排序的值設(shè)置成sorted set的score捂寿,將具體的數(shù)據(jù)設(shè)置成相應的value口四,每次只需要執(zhí)行一條ZADD命令即可。127.0.0.1:6379>zadd topN0smlt0fskl0fshkl0lzlsfs0wdhbx0wxg(integer)6127.0.0.1:6379>ZINCRBYtopN100000smlt"100000"127.0.0.1:6379>ZINCRBYtopN10000fskl"10000"127.0.0.1:6379>ZINCRBYtopN1000000fshkl"1000000"127.0.0.1:6379>ZINCRBYtopN100lzlsfs"100"127.0.0.1:6379>ZINCRBYtopN10wdhbx"10"127.0.0.1:6379>ZINCRBYtopN100000000wxg"100000000"127.0.0.1:6379>ZREVRANGEtopN021)"wxg"2)"fshkl"3)"smlt"127.0.0.1:6379>ZREVRANGEtopN02withscores1)"wxg"2)"100000000"3)"fshkl"4)"1000000"5)"smlt"6)"100000"127.0.0.1:6379>增zadd myzset2"two"3"three"添加兩個分數(shù)分別是2和3的兩個成員刪zrem myzset one two? ? ? ? ? ? ? ? 刪除多個成員變量,返回刪除的數(shù)量改zincrby myzset2one? ? ? ? ? ? ? ? 將成員 one 的分數(shù)增加2秦陋,并返回該成員更新后的分數(shù)查 zrange myzset0-1WITHSCORES返回所有成員和分數(shù),不加WITHSCORES,只返回成員zrank myzset one? ? ? ? ? ? ? ? ? ? 獲取成員one在Sorted-Set中的位置索引值蔓彩。0表示第一個位置zcard myzset? ? ? ? ? ? ? ? ? ? ? ? 獲取 myzset 鍵中成員的數(shù)量zcount myzset12獲取分數(shù)滿足表達式1<=score<=2的成員的數(shù)量zscore myzset three? ? ? ? ? ? ? ? 獲取成員 three 的分數(shù)zrangebyscore myzset12獲取分數(shù)滿足表達式1<score<=2的成員#-inf 表示第一個成員,+inf最后一個成員#limit限制關(guān)鍵字#2? 3? 是索引號zrangebyscore myzset-inf+inf limit23返回索引是2和3的成員zremrangebyscore myzset12刪除分數(shù)1<=score<=2的成員驳概,并返回實際刪除的數(shù)量zremrangebyrank myzset01刪除位置索引滿足表達式0<=rank<=1的成員zrevrange myzset0-1WITHSCORES按位置索引從高到低,獲取所有成員和分數(shù)#原始成員:位置索引從小到大one0two1#執(zhí)行順序:把索引反轉(zhuǎn)位置索引:從大到小? ? ? one1two0#輸出結(jié)果: two? onezrevrange myzset13獲取位置索引,為1,2,3的成員#相反的順序:從高到低的順序zrevrangebyscore myzset30獲取分數(shù)3>=score>=0的成員并以相反的順序輸出zrevrangebyscore myzset40limit12獲取索引是1和2的成員,并反轉(zhuǎn)位置索引

7. 發(fā)布訂閱

image.png

PUBLISH channel msg? ? 將信息 message 發(fā)送到指定的頻道 channelSUBSCRIBE channel [channel ...]? ? 訂閱頻道赤嚼,可以同時訂閱多個頻道UNSUBSCRIBE [channel ...]? ? 取消訂閱指定的頻道,如果不指定頻道,則會取消訂閱所有頻道PSUBSCRIBE pattern [pattern ...]? ? 訂閱一個或多個符合給定模式的頻道顺又,每個模式以 * 作為匹配符更卒,比如 it* 匹配所? 有以 it 開頭的頻道(it.news 、 it.blog 稚照、 it.tweets 等等)蹂空, news.* 匹配所有 以 news. 開頭的頻道(news.it 、 news.global.today 等等)果录,諸如此類PUNSUBSCRIBE [pattern [pattern ...]]? ? 退訂指定的規(guī)則,如果沒有參數(shù)則會退訂所有規(guī)則PUBSUB subcommand [argument [argument ...]]? ? 查看訂閱與發(fā)布系統(tǒng)狀態(tài)注意:使用發(fā)布訂閱模式實現(xiàn)的消息隊列上枕,當有客戶端訂閱channel后只能收到后續(xù)發(fā)布到該頻道的消息,之前發(fā)送的不會緩存弱恒,必須Provider和Consumer同時在線辨萍。發(fā)布訂閱例子:窗口1:127.0.0.1:6379> SUBSCRIBE baodi 窗口2:127.0.0.1:6379> PUBLISH baodi"jin tian zhen kaixin!"訂閱多頻道:窗口1:127.0.0.1:6379> PSUBSCRIBE wang*窗口2:127.0.0.1:6379> PUBLISH wangbaoqiang"jintian zhennanshou "

8、Redis事務

redis的事務是基于隊列實現(xiàn)的返弹。mysql的事務是基于事務日志和鎖機制實現(xiàn)的锈玉。redis是樂觀鎖機制。開啟事務功能時(multi)multi command1? ? ? command2command3command4exec discard4條語句作為一個組义起,并沒有真正執(zhí)行拉背,而是被放入同一隊列中。如果默终,這是執(zhí)行discard去团,會直接丟棄隊列中所有的命令,而不是做回滾穷蛹。exec當執(zhí)行exec時,對列中所有操作昼汗,要么全成功要么全失敗127.0.0.1:6379> set a bOK127.0.0.1:6379> MULTIOK127.0.0.1:6379> set a bQUEUED127.0.0.1:6379> set c dQUEUED127.0.0.1:6379> exec1)OK2)OK

9. redis樂觀鎖實現(xiàn)(模擬買票)

發(fā)布一張票set ticket 1窗口1:watch ticketmultiset ticket 0? ? ? 1---->0窗口2:multi set ticket 0 exec 窗口1:exec

10肴熏、 服務器管理命令

InfoClientlistClientkill ip:portconfigget*CONFIGRESETSTAT 重置統(tǒng)計CONFIGGET/SET 動態(tài)修改DbsizeFLUSHALL 清空所有數(shù)據(jù)select1FLUSHDB 清空當前庫MONITOR 監(jiān)控實時指令SHUTDOWN 關(guān)閉服務器關(guān)閉數(shù)據(jù)庫:redis-cli-a root shutdown

11、redis(Master-Replicaset) *****

11.1 原理:

1. 副本庫通過slaveof 10.0.0.51 6379命令,連接主庫,并發(fā)送SYNC給主庫 2. 主庫收到SYNC,會立即觸發(fā)BGSAVE,后臺保存RDB,發(fā)送給副本庫3. 副本庫接收后會應用RDB快照4. 主庫會陸續(xù)將中間產(chǎn)生的新的操作,保存并發(fā)送給副本庫5. 到此,我們主復制集就正常工作了6. 再此以后,主庫只要發(fā)生新的操作,都會以命令傳播的形式自動發(fā)送給副本庫.7. 所有復制相關(guān)信息,從info信息中都可以查到.即使重啟任何節(jié)點,他的主從關(guān)系依然都在.8. 如果發(fā)生主從關(guān)系斷開時,從庫數(shù)據(jù)沒有任何損壞,在下次重連之后,從庫發(fā)送PSYNC給主庫9. 主庫只會將從庫缺失部分的數(shù)據(jù)同步給從庫應用,達到快速恢復主從的目的

11.2 主從數(shù)據(jù)一致性保證

min-slaves-to-write1min-slaves-max-lag3

11.3 主庫是否要開啟持久化顷窒?

如果不開有可能蛙吏,主庫重啟操作源哩,造成所有主從數(shù)據(jù)丟失!

12. 主從復制實現(xiàn)

1鸦做、環(huán)境:準備兩個或兩個以上redis實例mkdir/data/638{0..2}配置文件示例:cat>>/data/6380/redis.conf<<EOFport6380daemonize yespidfile/data/6380/redis.pidloglevel noticelogfile"/data/6380/redis.log"dbfilename dump.rdbdir/data/6380requirepass123masterauth123EOFcat>>/data/6381/redis.conf<<EOFport6381daemonize yespidfile/data/6381/redis.pidloglevel noticelogfile"/data/6381/redis.log"dbfilename dump.rdbdir/data/6381requirepass123masterauth123EOFcat>>/data/6382/redis.conf<<EOFport6382daemonize yespidfile/data/6382/redis.pidloglevel noticelogfile"/data/6382/redis.log"dbfilename dump.rdbdir/data/6382requirepass123masterauth123EOF啟動:redis-server/data/6380/redis.confredis-server/data/6381/redis.confredis-server/data/6382/redis.conf主節(jié)點:6380從節(jié)點:6381励烦、63822、開啟主從:6381/6382命令行:redis-cli-p6381-a123SLAVEOF127.0.0.16380redis-cli-p6382-a123SLAVEOF127.0.0.163803泼诱、查詢主從狀態(tài) redis-cli-p6380-a123info replication redis-cli-p6381-a123info replication redis-cli-p6382-a123info replication

13 redis-sentinel(哨兵)

1坛掠、監(jiān)控2、自動選主治筒,切換(6381slaveof no one)3屉栓、2號從庫(6382)指向新主庫(6381)4、應用透明5耸袜、自動處理故障節(jié)點sentinel搭建過程mkdir/data/26380cd/data/26380vim sentinel.confport26380dir"/data/26380"sentinel monitor mymaster127.0.0.163801sentinel down-after-milliseconds mymaster5000sentinel auth-pass mymaster123啟動:[root@db0126380]# redis-sentinel/data/26380/sentinel.conf&>/tmp/sentinel.log&==============================如果有問題:1友多、重新準備1主2從環(huán)境2、kill掉sentinel進程3堤框、刪除sentinel目錄下的所有文件4域滥、重新搭建sentinel======================================停主庫測試:[root@db01~]# redis-cli-p6380shutdown[root@db01~]# redis-cli-p6381info replication啟動源主庫(6380),看狀態(tài)蜈抓。Sentinel管理命令:redis-cli-p26380PING :返回 PONG 启绰。SENTINELmasters :列出所有被監(jiān)視的主服務器SENTINELslaves<master name>SENTINELget-master-addr-by-name<master name>: 返回給定名字的主服務器的 IP 地址和端口號。SENTINELreset<pattern>: 重置所有名字和給定模式 pattern 相匹配的主服務器资昧。SENTINELfailover<master name>: 當主服務器失效時酬土, 在不詢問其他 Sentinel 意見的情況下, 強制開始一次自動故障遷移格带。

14. redis cluster

image.png

14.1 介紹

高性能

1撤缴、在多分片節(jié)點中,將16384個槽位叽唱,均勻分布到多個分片節(jié)點中2屈呕、存數(shù)據(jù)時,將key做crc16(key),然后和16384進行取模棺亭,得出槽位值(0-16383之間)3虎眨、根據(jù)計算得出的槽位值,找到相對應的分片節(jié)點的主節(jié)點镶摘,存儲到相應槽位上4嗽桩、如果客戶端當時連接的節(jié)點不是將來要存儲的分片節(jié)點,分片集群會將客戶端連接切換至真正存儲節(jié)點進行數(shù)據(jù)存儲

高可用:

在搭建集群時凄敢,會為每一個分片的主節(jié)點碌冶,對應一個從節(jié)點,實現(xiàn)slaveof的功能涝缝,同時當主節(jié)點down扑庞,實現(xiàn)類似于sentinel的自動failover的功能譬重。1、redis會有多組分片構(gòu)成(3組)2罐氨、redis cluster 使用固定個數(shù)的slot存儲數(shù)據(jù)(一共16384slot)3臀规、每組分片分得1/3 slot個數(shù)(0-5500? 5501-11000? 11001-16383)4、基于CRC16(key) % 16384 ====》值 (槽位號)栅隐。

14.2 規(guī)劃塔嬉、搭建過程:

6個redis實例,一般會放到3臺硬件服務器注:在企業(yè)規(guī)劃中约啊,一個分片的兩個分到不同的物理機邑遏,防止硬件主機宕機造成的整個分片數(shù)據(jù)丟失。端口號:7000-7005

安裝集群插件

EPEL源安裝ruby支持yum install ruby rubygems-y使用國內(nèi)源gem sources-lgem sources-a http://mirrors.aliyun.com/rubygems/gem sources--removehttps://rubygems.org/gem sources-lgem install redis-v3.3.3

集群節(jié)點準備

mkdir/data/700{0..5}cat>/data/7000/redis.conf<<EOFport7000daemonize yespidfile/data/7000/redis.pidloglevel noticelogfile"/data/7000/redis.log"dbfilename dump.rdbdir/data/7000protected-mode nocluster-enabled yescluster-config-file nodes.confcluster-node-timeout5000appendonly yesEOFcat>>/data/7001/redis.conf<<EOFport7001daemonize yespidfile/data/7001/redis.pidloglevel noticelogfile"/data/7001/redis.log"dbfilename dump.rdbdir/data/7001protected-mode nocluster-enabled yescluster-config-file nodes.confcluster-node-timeout5000appendonly yesEOFcat>>/data/7002/redis.conf<<EOFport7002daemonize yespidfile/data/7002/redis.pidloglevel noticelogfile"/data/7002/redis.log"dbfilename dump.rdbdir/data/7002protected-mode nocluster-enabled yescluster-config-file nodes.confcluster-node-timeout5000appendonly yesEOFcat>>/data/7003/redis.conf<<EOFport7003daemonize yespidfile/data/7003/redis.pidloglevel noticelogfile"/data/7003/redis.log"dbfilename dump.rdbdir/data/7003protected-mode nocluster-enabled yescluster-config-file nodes.confcluster-node-timeout5000appendonly yesEOFcat>>/data/7004/redis.conf<<EOFport7004daemonize yespidfile/data/7004/redis.pidloglevel noticelogfile"/data/7004/redis.log"dbfilename dump.rdbdir/data/7004protected-mode nocluster-enabled yescluster-config-file nodes.confcluster-node-timeout5000appendonly yesEOFcat>>/data/7005/redis.conf<<EOFport7005daemonize yespidfile/data/7005/redis.pidloglevel noticelogfile"/data/7005/redis.log"dbfilename dump.rdbdir/data/7005protected-mode nocluster-enabled yescluster-config-file nodes.confcluster-node-timeout5000appendonly yesEOF

啟動節(jié)點:

redis-server/data/7000/redis.conf redis-server/data/7001/redis.conf redis-server/data/7002/redis.conf redis-server/data/7003/redis.conf redis-server/data/7004/redis.conf redis-server/data/7005/redis.conf[root@db01 ~]# ps-ef |grep redisroot88541003:56?00:00:00redis-server*:7000[cluster]root88581003:56?00:00:00redis-server*:7001[cluster]root88601003:56?00:00:00redis-server*:7002[cluster]root88641003:56?00:00:00redis-server*:7003[cluster]root88661003:56?00:00:00redis-server*:7004[cluster]root88741003:56?00:00:00redis-server*:7005[cluster]

將節(jié)點加入集群管理

redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 \127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

集群狀態(tài)查看

集群主節(jié)點狀態(tài)redis-cli-p7000cluster nodes|grep master集群從節(jié)點狀態(tài)redis-cli-p7000cluster nodes|grep slave

14.3 集群節(jié)點管理

增加新的節(jié)點

mkdir/data/7006mkdir/data/7007cat>/data/7006/redis.conf<<EOFport7006daemonize yespidfile/data/7006/redis.pidloglevel noticelogfile"/data/7006/redis.log"dbfilename dump.rdbdir/data/7006protected-mode nocluster-enabled yescluster-config-file nodes.confcluster-node-timeout5000appendonly yesEOFcat>/data/7007/redis.conf<<EOFport7007daemonize yespidfile/data/7007/redis.pidloglevel noticelogfile"/data/7007/redis.log"dbfilename dump.rdbdir/data/7007protected-mode nocluster-enabled yescluster-config-file nodes.confcluster-node-timeout5000appendonly yesEOFredis-server/data/7006/redis.conf redis-server/data/7007/redis.conf

添加主節(jié)點:

redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000

轉(zhuǎn)移slot(重新分片)

redis-trib.rb reshard 127.0.0.1:7000

添加一個從節(jié)點

redis-trib.rb add-node --slave --master-id 8ff9ef5b78e6da62bd7b362e1fe190cba19ef5ae 127.0.0.1:7007 127.0.0.1:7000

14.4 刪除節(jié)點

將需要刪除節(jié)點slot移動走

redis-trib.rb reshard 127.0.0.1:700049257f251824dd815bc7f31e1118b670365e861a 127.0.0.1:70060-1364 5461-6826 10923-122871365? ? ? 1366? ? 1365

刪除一個節(jié)點

刪除master節(jié)點之前首先要使用reshard移除master的全部slot,然后再刪除當前節(jié)點redis-trib.rb del-node 127.0.0.1:7006 8ff9ef5b78e6da62bd7b362e1fe190cba19ef5ae---------------------設(shè)置redis最大內(nèi)存config set maxmemory 102400000---------------------

15.? redis的多API支持

python為例yum install-y python36 python3-Vyum install-y python36-pippip3 install redis pip3 install redis-py-cluster++++++++++++源碼方式+++++++++++++++https://redis.io/clients下載redis-py-master.zip安裝驅(qū)動:unzip redis-py-master.zipcd redis-py-masterpython3 setup.py installredis cluster的連接并操作(python2.7.2以上版本才支持redis cluster恰矩,我們選擇的是3.6)https://github.com/Grokzen/redis-py-cluster安裝redis-cluser的客戶端程序cd redis-py-cluster-unstablepython3 setup.py install+++++++++++++++++++++++++++++++++

對redis的單實例進行連接操作

[root@db01~]# redis-server /data/6379/redis.conf python3>>>import redis>>>r=redis.StrictRedis(host='10.0.0.51',port=6379,db=0,password='123456')>>>r.set('oldboy','oldguo')>>>r.get('oldboy')

sentinel集群連接并操作

[root@db01~]# redis-server /data/6380/redis.conf[root@db01~]# redis-server /data/6381/redis.conf[root@db01~]# redis-server /data/6382/redis.conf [root@db01~]# redis-sentinel /data/26380/sentinel.conf &--------------------------------## 導入redis sentinel包>>>from redis.sentinel importSentinel##指定sentinel的地址和端口號>>>sentinel=Sentinel([('localhost',26380)],socket_timeout=0.1)##測試记盒,獲取以下主庫和從庫的信息>>>sentinel.discover_master('mymaster')>>>sentinel.discover_slaves('mymaster')

配置讀寫分離

#寫節(jié)點>>>master=sentinel.master_for('mymaster',socket_timeout=0.1,password="123")#讀節(jié)點>>>slave=sentinel.slave_for('mymaster',socket_timeout=0.1,password="123")###讀寫分離測試? key? ? >>>master.set('oldboy','123')>>>slave.get('oldboy')

python連接rediscluster集群測試

使用python3>>>fromredisclusterimportStrictRedisCluster>>>startup_nodes=[{"host":"127.0.0.1","port":"7000"},{"host":"127.0.0.1","port":"7001"},{"host":"127.0.0.1","port":"7002"}]### Note: decode_responses must be set to True when used with python3? >>>rc=StrictRedisCluster(startup_nodes=startup_nodes,decode_responses=True)>>>rc.set("foo","bar")True>>>print(rc.get("foo"))'bar'

16.一些概念

緩存穿透

概念訪問一個不存在的key,緩存不起作用外傅,請求會穿透到DB纪吮,流量大時DB會掛掉。解決方案采用布隆過濾器萎胰,使用一個足夠大的bitmap碾盟,用于存儲可能訪問的key,不存在的key直接被過濾技竟;訪問key未在DB查詢到值冰肴,也將空值寫進緩存,但可以設(shè)置較短過期時間榔组。

緩存雪崩

概念大量的key設(shè)置了相同的過期時間熙尉,導致在緩存在同一時刻全部失效,造成瞬時DB請求量大搓扯、壓力驟增检痰,引起雪崩。解決方案可以給緩存設(shè)置過期時間時加上一個隨機值時間锨推,使得每個key的過期時間分布開來铅歼,不會集中在同一時刻失效。

緩存擊穿

概念

一個存在的key换可,在緩存過期的一刻椎椰,同時有大量的請求,這些請求都會擊穿到DB沾鳄,造成瞬時DB請求量大俭识、壓力驟增。

解決方案

在訪問key之前洞渔,采用SETNX(set if not exists)來設(shè)置另一個短期key來鎖住當前key的訪問套媚,訪問結(jié)束再刪除該短期key。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末磁椒,一起剝皮案震驚了整個濱河市堤瘤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌浆熔,老刑警劉巖本辐,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異医增,居然都是意外死亡慎皱,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門叶骨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來茫多,“玉大人,你說我怎么就攤上這事忽刽√煲荆” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵跪帝,是天一觀的道長今膊。 經(jīng)常有香客問我,道長伞剑,這世上最難降的妖魔是什么斑唬? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮黎泣,結(jié)果婚禮上恕刘,老公的妹妹穿的比我還像新娘。我一直安慰自己聘裁,他們只是感情好雪营,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著衡便,像睡著了一般献起。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上镣陕,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天谴餐,我揣著相機與錄音,去河邊找鬼呆抑。 笑死岂嗓,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的鹊碍。 我是一名探鬼主播厌殉,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼食绿,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了公罕?” 一聲冷哼從身側(cè)響起器紧,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎楼眷,沒想到半個月后铲汪,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡罐柳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年掌腰,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片张吉。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡齿梁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出芦拿,到底是詐尸還是另有隱情士飒,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布蔗崎,位于F島的核電站酵幕,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏缓苛。R本人自食惡果不足惜芳撒,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望未桥。 院中可真熱鬧笔刹,春花似錦、人聲如沸冬耿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽亦镶。三九已至日月,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間缤骨,已是汗流浹背爱咬。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留绊起,地道東北人精拟。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蜂绎。 傳聞我的和親對象是個殘疾皇子栅表,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容