Redis 是我們在開發過程中經常會用到的內存數據庫,尤其是在Python的第三方模塊Redis-py的支持下,在Python中使用Redis及其方便。
但是在有些情況下,我們無法使用像Redis-py這樣的第三方模塊(比如QMT),這時候就需要自己實現一個簡易版的Redis-py了。
本文將教大家如何用20行代碼,制作一個簡易版的Redis客戶端,不過僅以GET命令為例,其他命令的用法也差不多。
1.準備
開始之前,你要確保Python和pip已經成功安裝在電腦上,如果沒有,可以訪問這篇文章:超詳細Python安裝指南 進行安裝。
**(可選1) **如果你用Python的目的是數據分析,可以直接安裝Anaconda:Python數據分析與挖掘好幫手—Anaconda,它內置了Python和pip.
**(可選2) **此外,推薦大家用VSCode編輯器,它有許多的優點:Python 編程的最好搭檔—VSCode 詳細指南。
2.原理剖析
其實通過Redis GET返回的數據就是一些字符串,這些字符串的格式如下:
b'$466rnx80x04x95xc7x01x00x00x00x00x00x00]x94(x8cx06000957x94x8cx06002031x94x8cx06000899x94x8cx06300339x94x8cx06002090x94x8cx06601016x94x8cx06002547x94x8cx06002863x94x8cx06002591x94x8cx06002514x94x8cx06000629x94x8cx06002204x94x8cx06000544x94x8cx06002374x94x8cx06000821x94x8cx06000625x94x8cx06000158x94x8cx06002703x94x8cx06002866x94x8cx06600686x94x8cx06002796x94x8cx06300598x94x8cx06002101x94x8cx06002454x94x8cx06000970x94x8cx06000631x94x8cx06002121x94x8cx06600348x94x8cx06600996x94x8cx06002080x94x8cx06002194x94x8cx06002466x94x8cx06300663x94x8cx06002616x94x8cx06000665x94x8cx06600992x94x8cx06300750x94x8cx06300059x94x8cx06002047x94x8cx06002997x94x8cx06000521x94x8cx06002594x94x8cx06002261x94x8cx06002125x94x8cx06002085x94x8cx06002168x94x8cx06002665x94x8cx06002523x94x8cx06603067x94x8cx06002432x94e.rn'
可見其是一個bytes字符串,開頭$xxx是此數據的長度,rn作為分割符,后面緊跟著的就是你的原始數據內容,最后才是rn作為結尾。
根據這個返回內容,我們就可以制作一個簡易的客戶端用于在無法引用第三方模塊的環境中接收Redis信息。
3.編寫簡易Redis客戶端
與Redis通信,我們只需要用Python原生的socket模塊即可。
import socket
import pickle
REDIS_HOST = "127.0.0.1"
REDIS_PORT = 6379
# 創建 socket 對象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 連接服務,指定主機和端口
s.connect((REDIS_HOST, REDIS_PORT))
s.close()
這樣就與你的Redis服務器連接上了,接下來只需要向socket發送你的命令并receive即可獲取對應的內容:
import socket
import pickle
REDIS_HOST = "127.0.0.1"
REDIS_PORT = 6379
# 創建 socket 對象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 連接服務,指定主機和端口
s.connect((REDIS_HOST, REDIS_PORT))
# GET 某個 KEY 的內容
s.send("GET RQB_keys_20220719 rn".encode("utf-8"))
# 接收小于 1M 的數據
msg = s.recv(1024 * 1024)
s.close()
print(msg)
# b'$466rnx80x04x95xc7x01x00x00x00x00x00x00]x94(x8cx06000957x94x8cx06002031x94x8cx06000899x94x8cx06300339x94x8cx06002090x94x8cx06601016x94x8cx06002547x94x8cx06002863x94x8cx06002591x94x8cx06002514x94x8cx06000629x94x8cx06002204x94x8cx06000544x94x8cx06002374x94x8cx06000821x94x8cx06000625x94x8cx06000158x94x8cx06002703x94x8cx06002866x94x8cx06600686x94x8cx06002796x94x8cx06300598x94x8cx06002101x94x8cx06002454x94x8cx06000970x94x8cx06000631x94x8cx06002121x94x8cx06600348x94x8cx06600996x94x8cx06002080x94x8cx06002194x94x8cx06002466x94x8cx06300663x94x8cx06002616x94x8cx06000665x94x8cx06600992x94x8cx06300750x94x8cx06300059x94x8cx06002047x94x8cx06002997x94x8cx06000521x94x8cx06002594x94x8cx06002261x94x8cx06002125x94x8cx06002085x94x8cx06002168x94x8cx06002665x94x8cx06002523x94x8cx06603067x94x8cx06002432x94e.rn'
請注意,recv里你設定的大小會直接占用內存,所以請設定一個適宜的數目,或者從返回值中的美元符后的數字判斷你需要接收的數據大小。
比如第一次請求,你只接收1024個字節,拿到 $xxx 這個長度后,重新send一次命令,再 s.recv(xxx) 長度。
上述例子中得到的內容是redis的格式,我們需要把rn給去除掉,并只取中間的數據便是我們存入redis的原始數據。
import pickle
def get_msg(msg):
msg_new = msg.split(b"rn")[1]
msg = pickle.loads(msg_new)
return msg
因為我的原始內容是pickle格式,因此我在取出原始數據后使用pickle.loads便能拿到我想要的內容,完整代碼如下:
import socket
import pickle
REDIS_HOST = "127.0.0.1"
REDIS_PORT = 6379
# 創建 socket 對象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 連接服務,指定主機和端口
s.connect((REDIS_HOST, REDIS_PORT))
# GET 某個 KEY 的內容
s.send("GET RQB_keys_20220719 rn".encode("utf-8"))
# 接收小于 1M 的數據
msg = s.recv(1024 * 1024)
s.close()
def get_msg(msg):
msg_new = msg.split(b"rn")[1]
msg = pickle.loads(msg_new)
return msg
print(get_msg(msg))
效果如下:
['000957', '002031', '000899', '300339', '002090', '601016', '002547', '002863', '002591', '002514', '000629', '002204', '000544', '002374', '000821', '000625', '000158', '002703', '002866', '600686', '002796', '300598', '002101', '002454', '000970', '000631', '002121', '600348', '600996', '002080', '002194', '002466', '300663', '002616', '000665', '600992', '300750', '300059', '002047', '002997', '000521', '002594', '002261', '002125', '002085', '002168', '002665', '002523', '603067', '002432']
在QMT等會限制第三方模塊的軟件中,使用這樣的方式訪問Redis,就不會再遇到白名單的限制了。
-
內存
+關注
關注
8文章
3019瀏覽量
74005 -
開發
+關注
關注
0文章
370瀏覽量
40836 -
數據庫
+關注
關注
7文章
3794瀏覽量
64362 -
Redis
+關注
關注
0文章
374瀏覽量
10871
發布評論請先 登錄
相關推薦
評論