-
Redis介紹
-
特點及優點
1、開源的,使用C編寫,基於內存且支持持久化 2、高性能的Key-Value的NoSQL數據庫 3、支持數據類型豐富,字符串strings,散列hashes,列表lists,集合sets,有序集合sorted sets 等等 4、支持多種編程語言(C C++ Python Java PHP ... )
-
與其他數據庫對比
1、MySQL : 關係型數據庫,表格,基於磁盤,慢 2、MongoDB:鍵值對文檔型數據庫,值爲JSON文檔,基於磁盤,慢,存儲數據類型單一 3、Redis的誕生是爲了解決什麼問題?? 解決硬盤IO帶來的性能瓶頸
-
應用場景
1、使用Redis來緩存一些經常被用到、或者需要耗費大量資源的內容,通過這些內容放到redis裏面,程序可以快速讀取這些內容 2、一個網站,如果某個頁面經常會被訪問到,或者創建頁面時消耗的資源比較多,比如需要多次訪問數據庫、生成時間比較長等, 我們可以使用redis將這個頁面緩存起來,減輕網站負擔,降低網站的延遲,比如說網站首頁等 3、比如新浪微博 # 新浪微博,基於TB級的內存數據庫 # 內容 :存儲在MySQL數據庫 # 關係 :存儲在redis數據庫 # 數字 :粉絲數量,關注數量,存儲在redis數據庫 # 消息隊列
-
DB-Engines 數據庫流行度排行榜2019年11月最新排名
-
redis 版本
1、最新版本:5.0 2、常用版本:2.4、2.6、2.8 3.0(里程碑)、3.2、3.4、4.0、5.0 3、圖形界面管理工具(寫的一般) RedisDesktopManager # 爲了解決負載問題,所以發明了redis
-
誕生歷程
# 1、歷史 LLOOGG.com 幫助別的網站統計用戶信息,各個網站發送的瀏覽記錄都會存儲到存儲隊列,5-10000條記錄,多餘5條需要收費 # 2、原理 FIFO機制,先進先出,滿了進一條就出一條,網站越多,隊列越多,推入和彈出操作越多 # 3、技術及問題 開始使用MySQL進行硬盤讀寫,速度很慢,導致無法實時顯示,所以自己寫了一個列表結構的內存數據庫,程序性能不會受到硬盤IO的限制,加了持久化的功能 # 4、redis數據庫戛然而生
-
redis 附加功能
1、持久化 將內存中數據保存到磁盤中,保證數據安全,方便進行數據備份和恢復 2、發佈與訂閱功能 將消息同時分發給多個客戶端,用於構建廣播系統 3、過期鍵功能 爲鍵設置一個過期時間,讓它在指定時間內自動刪除 <節省內存空間> # 音樂播放器,日播放排名,過期自動刪除 4、事務功能 原子的執行多個操作 5、主從複製 6、Sentinel哨兵
-
-
Redis安裝
-
Ubuntu
# 安裝 sudo apt-get install redis-server # 服務端啓動 sudo /etc/init.d/redis-server start | stop | restart | status # 客戶端連接 redis-cli -h IP地址 -p 6379 -a 密碼 redis-cli 127.0.0.1:6379>ping PONG
-
Windows
1、下載安裝包 https://github.com/ServiceStack/redis-windows/blob/master/downloads/redis-64.3.0.503.zip 2、解壓 3、啓動服務端 雙擊解壓後的 redis-server.exe 4、客戶端連接 雙擊解壓後的 redis-cli.exe # 問題:關閉終端後服務終止 # 解決:將Redis服務安裝到本地服務 1、重命名 redis.windows.conf 爲 redis.conf,作爲redis服務的配置文件 2、cmd命令行,進入到redis-server.exe所在目錄 3、執行:redis-server --service-install redis.conf --loglevel verbose 4、計算機-管理-服務-Redis-啓動 # 卸載 到 redis-server.exe 所在路徑執行: 1、redis-server --service-uninstall 2、sc delete Redis
-
-
配置文件詳情
-
配置文件所在路徑
1、Ubuntu /etc/redis/redis.conf 2、windows 下載解壓後的redis文件夾中 redis.windows.conf redis.conf
-
設置連接密碼
1、requirepass 密碼(500行) 2、重啓服務 sudo /etc/init.d/redis-server restart 3、客戶端連接 redis-cli -h 127.0.0.1 -p 6379 -a 123456 127.0.0.1:6379>ping
-
允許遠程連接
1、註釋掉本地IP地址綁定 69行: # bind 127.0.0.1 ::1 2、關閉保護模式(默認開啓,把yes改爲no) 88行: protected-mode no 3、重啓服務 sudo /etc/init.d/redis-server restart
-
遠程連接測試(Windows連接Ubuntu的Redis服務)
# cmd命令行 1、d: 2、cd Redis3.0 3、redis-cli -h x.x.x.x 4、x.x.x.x:6379>ping # RedisDesktopManage 連接,注意windows防火牆問題(關閉)
-
-
數據類型
-
字符串類型(string)
-
特點
字符串、數字、都會轉化爲字符串來存儲
-
基本命令
1、set key value 2、setnx key value 3、set key value ex seconds 4、get key 5、mset key1 value1 key2 value2 6、mget key1 key2 key3 7、stren key # 數字操作 8、incr key 9、decr key
-
擴展命令
1、append key value 2、setrange key index value 3、getrange key start stop 4、incrby key step 5、decrby key step
-
常用命令
set | get命令 作用: 設置鍵值,獲取鍵對應的值 命令格式: set key value get key set命令之 - setnx # 鍵不存在,進行設置,如果鍵已經存在,則不進行任何操作 setnx key value : 鍵不存在時才能進行設置(重要) set命令之 - ex 作用: 設置過期時間 命令格式: set key value ex seconds mset | mget mset key1 value1 key2 value2 key3 value3 ... ... mget key1 key2 key3 ... ... 作用: 同時設置多個值,獲取多個值
-
鍵命名規範
利用層級關係 mset dayin:email [email protected] dy:email [email protected]
-
strlen命令
作用: 獲取值的長度 命令格式: strlen key 127.0.0.1:6379> strlen name (integer) 11 127.0.0.1:6379>
-
字符串索引操作
setrange key 索引值 value 作用: 從索引值開始,value替換原內容 127.0.0.1:6379> get message "hello world" 127.0.0.1:6379> setrange message 6 'dayin' (integer) 12 127.0.0.1:6379> get message "hello dayin" 127.0.0.1:6379> getrange key 起始值 終止值 作用: 獲取指定範圍切片內容 127.0.0.1:6379> get message "hello dayin" 127.0.0.1:6379> getrange message 0 4 "hello" 127.0.0.1:6379> getrange message 0 -1 "hello dayin"
-
append key value
作用: 追加拼接value的值 127.0.0.1:6379> set message 'hello ' OK 127.0.0.1:6379> append message 'world' (integer) 11 127.0.0.1:6379> get message "hello world" 127.0.0.1:6379>
-
整數操作
INCRBY key 步長 DECRBY key 步長 NCR key : +1操作 DECR key : -1操作 應用場景: 微博粉絲增加或減少就可以使用
-
浮點數操作
incrbyfloat key increment
-
string 命令彙總
# 字符串操作 1、set key value 2、setnx key value 3、get key 3、mset key1 value1 key2 value2 key3 value3 4、mget key1 key2 ke y3 5、set key value ex seconds 6、strlen key # 數字操作 7、incrby key 步長 8、decrby key 步長 9、incr key 10、decr key 11、incrbyfloat key number # 設置過期時間的兩種方式 # 方式一 1、set key value ex 3 # 方式二 1、set key value 2、expire key 5 # 秒 3、pexpire key 5 # 毫秒 # 查看存活時間 ttl key # 刪除過期 persist key
-
通用命令彙總
# 切換庫 select number(0-15) # 查看所有鍵 keys * # 鍵類型 TYPE key # 鍵是否存在 exists key # 刪除鍵 del key # 鍵重命名 rename key newkey # 返回舊值並設置新值(如果鍵不存在,就創建並賦值) getset key value # 清除當前庫中所有數據(慎用) flushdb # 清除所有庫中所有數據(慎用) flushall
-
string 數據類型注意
# key值取值原則 1、key值不宜過長,消耗內存,且在數據中查找這類鍵值的計算成本高 2、不宜過短,可讀性較差 # 值 1、一個字符串類型的值最多能存儲512M內容
-
-
列表數據類型
-
特點
1、元素是字符串類型 2、列表頭尾增刪快,中間增刪慢,增刪元素是常態 3、元素可重複 4、最多可包含2^32 -1個元素 5、索引同python列表
-
頭尾壓入元素(LPUSH | RPUSH)
# LPUSH : Left # RPUSH : Right ['lucy','tom','10']
-
查看|設置 列表元素
查看(LRANGE) # lrange key start stop lrange mylist1 0 2 # 顯示前3個元素 lrange mylist1 0 -1 # 顯示列表中所有元素 獲取指定位置元素(LINDEX) lindex key index 設置指定位置元素的值(LSET) lset key index value 獲取列表長度(LLEN) llen key
-
頭尾彈出元素(LPOP | RPOP)
LPOP key : 從列表頭部彈出一個元素 RPOP key : 從列表尾部彈出一個元素 RPOPLPUSH source destination : 從一個列表尾部彈出元素壓入到另一個列表頭部 rpoplpush mylist1 mylist2
-
移除指定元素(LREM)
LREM key count value count>0:表示從頭部開始向表尾搜索,移除與value相等的元素,數量爲count count<0:表示從尾部開始向表頭搜索,移除與value相等的元素,數量爲count count=0:移除表中所有與value相等的值 示例: lrem mylist 0 tom lrem mylist 1 tom lrem mylist -2 tom
-
去除指定範圍外元素(LTRIM)
LTRIM key start stop 應用場景: 保存微博評論最後500條 weibo:comments [評論,評論,。。。。。,。。。。] # LPUSH (考慮列表中元素順序) LTRIM weibo:comments 0 499 # RPUSH LRTIM weibo:comments -500 -1
-
列表中插入值(LINSERT)(瞭解)
LINSERT key BEFORE|AFTER value new_value key和pivot不存在,不進行任何操作 示例代碼 [1 2 3 4 5 2 ] LINSERT mylist after 2 8
-
阻塞彈出(BLPOP | BRPOP)(重要)
BLPOP key timeout BRPOP key timeout 1、如果彈出的列表不存在或者爲空,就會阻塞 2、超時時間設置爲0,就是永久阻塞,直到有數據可以彈出 3、如果多個客戶端阻塞再同一個列表上,使用First In First Service原則,先到先服務 示例: brpop mylist 0 # 永久阻塞 brpop mylist 3 # 超時時間3秒
-
列表常用命令總結
# 增 1、LPUSH key value1 value2 2、RPUSH key value1 value2 3、RPOPLPUSH source destination 4、LINSERT key after|before value newvalue # 查 5、LRANGE key start stop 6、LLEN key # 刪 7、LPOP key 8、RPOP key 9、BLPOP key timeout 10、BRPOP key timeout 11、LREM key count value 12、LTRIM key start stop # 微博評論500條 # 改 13、LSET key index newvalue
-
-
位圖操作
-
定義
1、位圖不是真正的數據類型,它是定義在字符串類型中 2、一個字符串類型的值最多能存儲512M字節的內容,位上限:2^32 # 1MB = 1024KB # 1KB = 1024Byte(字節) # 1Byte = 8bit(位)
-
強勢點
可以實時的進行統計,極其節省空間。官方在模擬1億2千8百萬用戶的模擬環境下, 在一臺MacBookPro上,典型的統計如“日用戶數”的時間消耗小於50ms, 佔用16MB內存
-
常用命令
# 設置某一位上的值(offset是偏移量,從0開始) setbit key offset value # 獲取某一位上的值 GETBIT key offset # 統計鍵所對應的值中有多少個 1 BITCOUNT key
-
應用場景案例
網站用戶的上線次數統計(尋找活躍用戶) 用戶名爲key,上線的天作爲offset,上線設置爲1 示例: 用戶名爲 user001 的用戶,今年第1天上線,第30天上線 SETBIT user001 0 1 SETBIT user001 29 1 BITCOUNT user001
-
-
Hash散列數據類型
-
定義
1、由field和關聯的value組成的鍵值對 2、field和value是字符串類型 3、一個hash中最多包含2^32-1個鍵值對
-
優點
1、節約內存空間 2、每創建一個鍵,它都會爲這個鍵儲存一些附加的管理信息(比如這個鍵的類型,這個鍵最後一次被訪問的時間等) 3、鍵越多,redis數據庫在儲存附件管理信息方面耗費內存越多,花在管理數據庫鍵上的CPU也會越多
-
缺點(不適合hash情況)
1、使用二進制位操作命令:SETBIT、GETBIT、BITCOUNT等,如果想使用這些操作,只能用字符串鍵 2、使用過期鍵功能:鍵過期功能只能對鍵進行過期操作,而不能對散列的字段進行過期操作
-
基本命令操作
# 1、設置單個字段 HSET key field value HSETNX key field value # 2、設置多個字段 HMSET key field value field value # 3、返回字段field個數 HLEN key # 4、判斷字段是否存在(不存在返回0) HEXISTS key field # 5、返回字段值 HGET key field # 6、返回多個字段值 HMGET key field filed # 7、返回所有的鍵值對 HGETALL key # 8、返回所有字段名 HKEYS key # 9、返回所有值 HVALS key # 10、刪除指定字段 HDEL key field field field # 11、在字段對應值上進行整數增量運算 HINCRBY key field increment # 12、在字段對應值上進行浮點數增量運算 HINCRBYFLOAT key field increment
-
應用場景:微博好友關注
1、用戶ID爲key,Field爲好友ID,Value爲關注時間 key field value user:10000 user:606 20190520 user:605 20190521 2、用戶維度統計 統計數包括:關注數、粉絲數、喜歡商品數、發帖數 用戶爲key,不同維度爲field,value爲統計數 比如關注了5人 HSET user:10000 fans 5 HINCRBY user:10000 fans 1
-
-
集合數據類型(set)
-
特點
1、無序、去重 2、元素是字符串類型 3、最多包含2^32-1個元素
-
基本命令
# 1、增加一個或者多個元素,自動去重 SADD key member1 member2 # 2、查看集合中所有元素 SMEMBERS key # 3、刪除一個或者多個元素,元素不存在自動忽略 SREM key member1 member2 # 3、隨機彈出元素(默認彈出一個) SPOP key [count] # 4、元素是否存在 SISMEMBER key member # 5、隨機返回集合中指定個數的元素,默認爲1個 SRANDOMMEMBER key [count] # 6、返回集合中元素的個數,不會遍歷整個集合,只是存儲在鍵當中了 SCARD key # 7、把元素從源集合移動到目標集合 SMOVE source destination member # 8、差集(number1 1 2 3 number2 1 2 4) SDIFF key1 key2 # 9、差集保存到另一個集合中 SDIFFSTORE destination key1 key2 # 10、交集 SINTER key1 key2 SINTERSTORE destination key1 key2 # 11、並集 SUNION key1 key2 SUNIONSTORE destination key1 key2
-
應用場景: 新浪微博的共同關注
需求: 當用戶訪問另一個用戶的時候,會顯示出兩個用戶共同關注過哪些相同的用戶 設計: 將每個用戶關注的用戶放在集合中,求交集即可 實現: user001 = {'peiqi','qiaozhi','danni'} user002 = {'peiqi','qiaozhi','lingyang'} user001和user002的共同關注爲: # SINTERSTORE user_all user001 user002 # SINTER user001 user002
-
-
有序集合 sortedset
-
特點
1、有序、去重 2、元素是字符串類型 3、每個元素都關聯着一個浮點數分值(score),並按照分值從小到大的順序排列集合中的元素(分值可以相同) 4、最多包含2^32-1元素
-
示例
-
一個保存了水果價格的有序集合
-
一個保存了員工薪水的有序集合
-
-
增加
zadd key score member # 在有序集合中添加一個成員 zadd key score member # 查看指定區間元素(升序) zrange key start stop [withscores] # 查看指定區間元素(降序) ZREVRANGE key start stop [withscores] # 查看指定元素的分值 ZSCORE key member # 返回指定區間元素 # offset : 跳過多少個元素 # count : 返回幾個 # 小括號 : 開區間 zrangebyscore salary (6000 (8000 zrangebyscore key min max [withscores] [limit offset count] limit 2 3 # 顯示第 3 4 5 三個元素 # 刪除成員 zrem key member # 增加或者減少分值 zincrby key increment member # 返回元素排名 zrank key member # 返回元素逆序排名 zrevrank key member # 刪除指定區間內的元素 zremrangebyscore key min max # 返回集合中元素個數 zcard key # 返回指定範圍中元素的個數 zcount key min max zcount fruits 4 7 zcount fruits (4 7 # 並集 zunionstore destination numkeys key [weights 權重值] [AGGREGATE SUM|MIN|MAX] # zunionstore zset4 2 zset1 zset2 aggregate max # 交集:和並集類似,只取相同的元素 ZINTERSTORE destination numkeys key1 key2 WEIGHTS weight AGGREGATE SUM|MIN|MAX
-
應用場景1:網易雲音樂排行榜
1、每首歌的歌名作爲元素(先不考慮重複) 2、每首歌的播放次數作爲分值 3、使用ZREVRANGE來獲取播放次數最多的歌曲
-
應用場景2: 京東商品暢銷榜
# 第1天 ZADD mobile-001 5000 'huawei' 4000 'oppo' 3000 'iphone' # 第2天 ZADD mobile-002 5200 'huawei' 4300 'oppo' 3230 'iphone' # 第3天 ZADD mobile-003 5500 'huawei' 4660 'oppo' 3580 'iphone' 問題:如何獲取三款手機的銷量排名? # 1、ZADD mobile-003 5500 'huawei' 4660 'oppo' 3580 'iphone' 2、ZUNIONSTORE mobile-001:003 mobile-001 mobile-002 mobile-003 AGGREGATE MAX
-
-
-
與Python交互
-
模塊
-
Ubuntu
sudo pip3 install redis
-
Windows
python -m pip install redis
-
使用流程
import redis # 創建數據庫連接對象 r = redis.Redis(host='127.0.0.1',port=6379,db=0,password='123456')
-
Python操作字符串類型
import redis r = redis.Redis(host='192.168.43.49',port=6379,password='123456',db=0) r.set('mystring','python') # b'python' print(r.get('mystring')) # False print(r.setnx('mystring','socket')) # mset:參數爲字典 r.mset({'mystring2':'mysql','mystring3':'mongodb'}) # mget:結果爲一個列表 print(r.mget('mystring','mystring2','mystring3')) # mystring長度:6 print(r.strlen('mystring')) # 數字類型操作 r.set('number',10) r.incrby('number',5) r.decrby('number',5) r.incr('number') r.decr('number') r.incrbyfloat('number',6.66) r.incrbyfloat('number',-6.66) # b'10' print(r.get('number'))
-
案例1:網易音樂排行榜(有序集合)
import redis r = redis.Redis(host='192.168.43.49',port=6379,password='123456',db=0) r.zadd('ranking',{'song1':1,'song2':1,'song3':1,'song4':1}) r.zadd('ranking',{'song5':1,'song6':1,'song7':1}) r.zadd('ranking',{'song8':1,'song9':1}) r.zincrby('ranking',50,'song3') r.zincrby('ranking',60,'song5') r.zincrby('ranking',80,'song7') # 獲取前10名 rlist = r.zrevrange('ranking',0,2,withscores=True) i = 1 for r in rlist: print('第%d名:%s' % (i,r[0].decode())) i += 1
-
案例2: 京東商品暢銷榜
import redis r = redis.Redis(host='192.168.43.49',port=6379,password='123456',db=0) # 第1天 day01_dict = { 'huawei' : 5000, 'oppo' : 4000, 'iphone' : 3000 } # 第2天 day02_dict = { 'huawei' : 5200, 'oppo' : 4300, 'iphone' : 3230 } # 第3天 day03_dict = { 'huawei' : 5500, 'oppo' : 4660, 'iphone' : 3580 } r.zadd('mobile-day01',day01_dict) r.zadd('mobile-day02',day02_dict) r.zadd('mobile-day03',day03_dict) r.zunionstore('mobile-day01:03',('mobile-day01','mobile-day02','mobile-day03'),aggregate='max') rlist = r.zrevrange('mobile-day01:03',0,-1,withscores=True) i = 1 for r in rlist: print('第{}名:{}'.format(i,r[0].decode()) )
-
-
end…