1)Redis:REmote DIctionary Server(遠程字典服務器)html
2)是徹底開源免費的,用C語言編寫的,遵照BSD開源協議,python
是一個高性能的(key/value)分佈式內存數據庫,基於內存運行,mysql
並支持持久化的NoSQL數據庫,是當前最熱門的NoSql數據庫之一,也被人們稱爲數據結構服務器。redis
3)Redis 與其餘 key - value 緩存產品有如下三個特色:sql
3.1)Redis支持數據的持久化,能夠將內存中的數據保持在磁盤中,重啓的時候能夠再次加載進行使用數據庫
3.2)Redis不只僅支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲vim
3.3)Redis支持數據的備份,即master-slave模式的數據備份緩存
1)內存存儲和持久化:redis支持異步將內存中的數據寫到硬盤上,同時不影響繼續服務安全
2)取最新N個數據的操做,如:能夠將最新的10條評論的ID放在List集合服務器
3)模擬相似於HttpSession這種須要設定過時時間的功能
4)發佈、訂閱消息系統
5)定時器、計數器
因爲企業裏面作Redis開發,99%都是Linux版的運用和安裝,
幾乎不會涉及到Windows版。
安裝包括服務端和客戶端
在 Ubuntu 系統安裝 Redi 可使用如下命令:
sudo apt-get update
sudo apt-get install redis-server
啓動 Redis 服務
redis-server
或者
sudo redis-server /etc/redis/redis.conf
使用 redis 客戶端查看是否啓動
redis-cli
檢查是否安裝成功
127.0.0.1 是本機 IP ,6379 是 redis 服務端口。如今咱們輸入 PING 命令。
以上說明咱們已經成功安裝了redis
下載:打開redis官方網站(https://redis.io/),推薦下載穩定版本(stable)
http://www.redis.cn/
解壓
tar zxvf redis-3.2.5.tar.gz
複製:推薦放到usr/local目錄下
sudo mv -r redis-3.2.5/* /usr/local/redis/
進入redis目錄
cd /usr/local/redis/
生成
sudo make
測試
sudo make test
這段運行時間會較長
安裝:將redis的命令安裝到/usr/bin/目錄
sudo make install
啓動服務器:在桌面目錄
redis-server 或者 sudo redis-server /etc/redis/redis.conf 按ctrl+c中止
啓動客戶端:在新終端中運行以下代碼
redis-cli
運行命令
ping set 'a' '123'
當添加鍵值後,發如今當前運行的目錄下,建立了一個文件:dump.rdb,這個文件用於將數據持久化存儲
查看redis的版本有兩種方式:
4 1. 查詢服務端
redis-server --version
或者
redis-server -v
獲得的結果是:
Redis server v=3.0.6 sha=00000000:0 malloc=jemalloc-3.6.0 bits=64 build=687a2a319020fa42
redis-cli --version
或者
redis-cli -v
獲得的結果是:redis-cli 3.0.6
嚴格上說:經過 redis-cli 獲得的結果應該是redis-cli 的版本,可是 redis-cli 和redis-server 通常都是從同一套源碼編譯出的。因此應該是同樣的。
在原文件/usr/local/redis目錄下,文件redis.conf爲配置文件
已經移動到/etc/redis/目錄下,文件redis.conf爲配置文件
打開配置文件命令:sudo subl /etc/redis/redis.conf
綁定地址:若是須要遠程訪問,可將此行註釋
bind 127.0.0.1
建議不要修改
port 6379
推薦改成yes,以守護進程運行
daemonize no|yes
數據文件
dbfilename dump.rdb
設置數據文件存儲路徑
dir的默認值爲./,表示當前目錄
推薦改成:dir /var/lib/redis
注意,刪除後,插入數據重啓redis服務器才能看到數據庫
sudo cp /usr/local/redis/redis.conf /etc/redis/
ps ajx|grep redis
#推薦指定配置文件啓動
sudo redis-server /etc/redis/redis.conf
或者
sudo service redis start
sudo kill -9 redis的進程id
或者
sudo service redis stop
sudo service redis restart
當配置文件從新配置後,通常會重啓服務器這樣配置才生效
redis是key-value的數據,因此每一個數據都是一個鍵值對
鍵的類型是字符串
值的類型分爲五種:
數據操做的所有命令,
能夠查看redis中文網站(http://redis.cn/commands.html)
接下來逐個介紹操做各種型的命令
啓動redis服務
sudo redis-server /etc/redis/redis.conf
或者
sudo service redis start
啓動客戶端:在新終端中運行以下代碼
redis-cli
啓動後效果如圖
1.1.1 設置鍵值
set key value
SETEX key seconds value
注意,key和值不加引號也能夠
MSET key value [key value ...] 案例: mset 'key1' 'hello' 'key2' 'world'
根據鍵獲取值,若是不存在此鍵則返回nil,get不區分大小寫也就是說get和GET均可以獲得數據
GET key
MGET key [key ...] 案例 mget 'key1' 'key2'
INCR key
INCRBY key increment
DECR key
DECRBY key decrement
APPEND key value
STRLEN key
KEYS pattern
EXISTS key [key ...]
TYPE key
DEL key [key ...]
爲給定 key 設置生存時間,當 key 過時時(生存時間爲 0 ),它會被自動刪除。
能夠對一個已經帶有生存時間的 key 執行 EXPIRE 命令,新指定的生存時間會取代舊的生存時間。沒有過時的是-1,過時的是-2
EXPIRE key seconds
查看有效時間,以秒爲單位
TTL key
hash用於存儲對象,對象的格式爲鍵值對
hash 特別適合用於存儲對象。相對於將對象的每一個字段存成單個string 類型。將一個對象
存儲在hash 類型中會佔用更少的內存,而且能夠更方便的存取整個對象。省內存的緣由是
新建一個hash 對象時開始是用zipmap(又稱爲small hash)來存儲的。這個zipmap 其實並
不是hash table,可是zipmap 相比正常的hash 實現能夠節省很多hash 自己須要的一些元
數據存儲開銷。儘管zipmap 的添加,刪除,查找都是O(n),可是因爲通常對象的field
數量都不太多。因此使用zipmap 也是很快的,也就是說添加刪除平均仍是O(1)。若是field
或者value 的大小超出必定限制後,redis 會在內部自動將zipmap 替換成正常的hash 實現.
這個限制能夠在配置文件中指定。
hash-max-zipmap-entries 64 #配置字段最多64 個
hash-max-zipmap-value 512 #配置value 最大爲512 字節
hset key field value 設置 hash field爲指定值,若是 key不存在,則建立
返回值:
若是 field 是哈希表中的一個新建域,而且值設置成功,返回 1 。
若是哈希表中域 field 已經存在且舊值已被新值覆蓋,返回 0 。
HSET key field value
例子:
hset py3 name '郭靖'
HMSET key field value [field value ...]
hmset py4 name 'gj' gender '0'
HGET key field
HMGET key field [field ...]
HGETALL key
HKEYS key
HLEN key
HVALS key
HEXISTS key field
HDEL key field [field ...]
1)列表的元素類型爲string
2)按照插入順序排序
3)在列表的頭部或者尾部添加元素
語法和案例
LPUSH key value [value ...]
案例
lpush py5 'abc' 'efg'
查看數據
查看類型
RPUSH key value [value ...]
具體案例
rpush py5 'hij' 'qlm'
查看插入的數據
LINSERT key BEFORE|AFTER pivot value
具體案例:
linsert py5 after 'abc' '123'
LSET key index value
LRANGE key start stop
例如:
lrange py5 2 -1
LPOP key
lpop py5
RPOP key
案例:
ppop py5
LTRIM key start stop
案例:
ltrim py5 1 2
LLEN key
LINDEX key index
1)無序集合
2)元素爲string類型
3)元素具備惟一性,不重複
SADD key member [member ...]
例子:
sadd py6 abc 123 defg
SMEMBERS key
例子:獲得py6集合全部元素
smembers py6
SCARD key
例如:查看py6集合元素的個數
scard py6
sadd py6 defg 123 abc 456
sadd py7 abc 123 world 456
SINTER key [key ...]
例如:求py6和py7兩個集合的交集
sinter py6 py7
SDIFF key [key ...]
例如:從py6中減掉py7中py6也存在的元素
sdiff py6 py7
例如:從py7中減掉py6中py7也存在的元素
sdiff py7 py6
SUNION key [key ...]
例如:
sunion py6 py7
SISMEMBER key member
1)sorted set,有序集合
2)元素爲string類型
3)元素具備惟一性,不重複
4)每一個元素都會關聯一個double類型的score,表示權重,經過權重將元素從小到大排序
5)元素的score能夠相同
ZADD key score member [score member ...]
ZRANGE key start stop
ZCARD key
ZCOUNT key min max
ZSCORE key member
發佈者不是計劃發送消息給特定的接收者(訂閱者),而是發佈的消息分到不一樣的頻道,不須要知道什麼樣的訂閱者訂閱。
訂閱者對一個或多個頻道感興趣,只需接收感興趣的消息,不須要知道什麼樣的發佈者發佈的。
發佈者和訂閱者的解耦合能夠帶來更大的擴展性和更加動態的網絡拓撲。
客戶端發到頻道的消息,將會被推送到全部訂閱此頻道的客戶端。
客戶端不須要主動去獲取消息,只須要訂閱頻道,這個頻道的內容就會被推送過來。
select 0
或者
select 1
說明,
SUBSCRIBE 頻道名稱 [頻道名稱 ...]
subscribe頻道名稱 [頻道名稱 ...]
直接使用Ctrl+c退出也能夠取消訂閱
UNSUBSCRIBE 頻道名稱 [頻道名稱 ...]
或者
unsubscribe 頻道名稱 [頻道名稱 ...]
由於訂閱平道後當前終端處於阻塞狀態,沒法輸入取出訂閱命令,那麼在使用Python代碼交互的時候,使用該該命令用於取消訂閱某個或者一些頻道。
PUBLISH 頻道 消息
或者
publish 平道 消息
一個master能夠擁有多個slave,一個slave又能夠擁有多個slave,如此下去,造成了強大的多級服務器集羣架構。
好比,將ip爲192.168.1.10的機器做爲主服務器,將ip爲192.168.1.11的機器做爲從服務器。
使用vim或者其餘文本工具找到redis.conf配置文件
sudo vim /etc/redis/redis.conf
設置主服務器的配置
bind 192.168.1.29
保存退出,而且重啓redis服務器
使用vim或者其餘文本工具找到redis.conf配置文件
sudo vim /etc/redis/redis.conf
注意:在slaveof後面寫主機ip,再寫端口,並且端口必須寫
bind 192.168.1.91
slaveof 192.168.1.29 6379
保存退出,而且重啓redis服務器
在master和slave分別執行info命令,查看輸出信息
redis-cli -h 192.168.1.29
set hello world
Slave機器上本身的ip,必定要指定,不然會沒有數據
get hello
到中文官網(http://redis.cn/clients.html)查找客戶端代碼
sudo pip3 install redis
unzip redis-py-master.zip cd redis-py-master sudo python setup.py install
import redis
try: red = redis.StrictRedis(host="192.168.31.114",port=6379) except Exception as e: print(e)
else: #name是key,hello world是值 red.set("name","hello world") #根據key獲得值 print(red.get("name"))#b'hello world'
運行效果:
#緩衝多條命令,而後一次性執行,減小服務器-客戶端之間TCP數據庫包,從而提升效率 pipe = red.pipeline() pipe.set('name', 'world') print(pipe.get('name')) #執行命令 pipe.execute()
模塊test.py代碼以下:
import redis class RedisHelper(): def __init__(self,host='192.168.31.114',port=6379): self.__redis = redis.StrictRedis(host, port) def get(self,key): if self.__redis.exists(key): return self.__redis.get(key) else: return "" def set(self,key,value): self.__redis.set(key,value) if __name__ == "__main__": red = RedisHelper() #name是key,hello world是值 red.set("name","hello world") #根據key獲得值 print(red.get("name"))#b'hello world'
業務過程以下:
輸入用戶名、密碼
密碼加密
判斷redis中是否記錄了用戶名,若是有則成功
若是redis中沒有用戶名,則到mysql中查詢
從mysql中查詢成功後,將用戶名記錄到redis中
import pymysql import redis class RedisHelp(object): def __init__(self,host="192.168.31.114",port=6379): self.__redis = redis.StrictRedis(host=host,port=port) def get(self,key): if self.__redis.exists(key): return self.__redis.get(key) else: return "" def set(self,key,value): self.__redis.set(key,value) class MySQLHelp(object): def __init__(self,host): self.host=host self.port=3306 self.user='afu' self.password='123456' self.db='python2' self.charset='utf8' #創建連接 def open(self): self.conn = pymysql.connect( host=self.host, port=self.port, user=self.user, password=self.password, db=self.db, charset=self.charset ) #執行sql語句和查詢數據 self.cursor = self.conn.cursor() #關閉連接,釋放資源 def close(self): self.cursor.close() self.conn.close() #獲得因此數據 def get_all(self,sql,params=[]): result = None try: #打開連接 self.open() self.cursor.execute(sql,params) #獲得數據 result = self.cursor.fetchall() return result except Exception as e: print(e) # self.close() return result # 獲得因此數據 def get_one(self, sql, params=[]): result = None try: # 打開連接 self.open() self.cursor.execute(sql, params) # 獲得數據 result = self.cursor.fetchone() self.close() return result except Exception as e: print(e) return result #增長,刪除,修改--提交事務 def cul(self, sql, params=[]): try: # 打開連接 self.open() count = self.cursor.execute(sql, params) # 提交事務 self.conn.commit() self.close() print("執行完畢!") return count except Exception as e: print(e) return None #增長數據 def insert(self,sql,params=[]): return self.cul(sql,params) #刪除 def delete(self,sql,params=[]): return self.cul(sql,params) # 修改 def update(self, sql, params=[]): return self.cul(sql, params)
from hashlib import sha1 re = RedisHelp(host="localhost") name = input("請輸入登陸帳號:") password = input("請登陸密碼:") #加密後的密碼 password = sha1(password.encode()).hexdigest() uname = re.get("uname").decode("utf-8") upwd = re.get("upwd").decode("utf-8") print(type(uname)) print(uname == name) if str(uname) == name: if str(upwd) == password: print("登陸成功,數據來自redis數據庫") else: print("密碼錯誤,數據來自redis數據庫") else: help = MySQLHelp("localhost") #(id,uname,upwd) sql = "select * from userinfos where uname = %s" params = [name] result = help.get_one(sql,params) # print(result) if result == None: print("帳號不存在") else: if result[1] == name and result[2] ==password: print("登陸成功!來自mysql") #保存數據到redis下次可使用 re.set("uname",name) re.set("upwd",password) else: print("密碼錯誤!")
運行結果: