A. python中的redis有多少個資料庫
跟Python沒有關系,是redis的問題
1、redis 中的每一個資料庫,都由一個 redisDb 的結構存儲。其中,redisDb.id 存儲著 redis 資料庫以整數表示的號碼。redisDb.dict 存儲著該庫所有的鍵值對數據。redisDb.expires 保存著每一個鍵的過期時間。
2、當redis 伺服器初始化時,會預先分配 16 個資料庫(該數量可以通過配置文件配置),所有資料庫保存到結構 redisServer 的一個成員 redisServer.db 數組中。當我們選擇資料庫 select number 時,程序直接通過 redisServer.db[number] 來切換資料庫。有時候當程序需要知道自己是在哪個資料庫時,直接讀取 redisDb.id 即可。
3、既然我們知道一個資料庫的所有鍵值都存儲在redisDb.dict中,那麼我們要知道如果找到key的位置,就有必要了解一下dict 的結構了:
typedef struct dict {
// 特定於類型的處理函數
dictType *type;
// 類型處理函數的私有數據
void *privdata;
// 哈希表(2個)
dictht ht[2];
// 記錄 rehash 進度的標志,值為-1 表示 rehash 未進行
int rehashidx;
// 當前正在運作的安全迭代器數量
int iterators;
} dict;
由上述的結構可以看出,redis 的字典使用哈希表作為其底層實現。dict 類型使用的兩個指向哈希表的指針,其中 0 號哈希表(ht[0])主要用於存儲資料庫的所有鍵值,而1號哈希表主要用於程序對 0 號哈希表進行 rehash 時使用,rehash 一般是在添加新值時會觸發,這里不做過多的贅述。所以redis 中查找一個key,其實就是對進行該dict 結構中的 ht[0] 進行查找操作。
4、既然是哈希,那麼我們知道就會有哈希碰撞,那麼當多個鍵哈希之後為同一個值怎麼辦呢?redis採取鏈表的方式來存儲多個哈希碰撞的鍵。也就是說,當根據key的哈希值找到該列表後,如果列表的長度大於1,那麼我們需要遍歷該鏈表來找到我們所查找的key。當然,一般情況下鏈表長度都為是1,所以時間復雜度可看作o(1)。
二、當redis 拿到一個key 時,如果找到該key的位置。
了解了上述知識之後,我們就可以來分析redis如果在內存找到一個key了。
1、當拿到一個key後, redis 先判斷當前庫的0號哈希表是否為空,即:if (dict->ht[0].size == 0)。如果為true直接返回NULL。
2、判斷該0號哈希表是否需要rehash,因為如果在進行rehash,那麼兩個表中者有可能存儲該key。如果正在進行rehash,將調用一次_dictRehashStep方法,_dictRehashStep 用於對資料庫字典、以及哈希鍵的字典進行被動 rehash,這里不作贅述。
3、計算哈希表,根據當前字典與key進行哈希值的計算。
4、根據哈希值與當前字典計算哈希表的索引值。
5、根據索引值在哈希表中取出鏈表,遍歷該鏈表找到key的位置。一般情況,該鏈表長度為1。
6、當 ht[0] 查找完了之後,再進行了次rehash判斷,如果未在rehashing,則直接結束,否則對ht[1]重復345步驟。
到此我們就找到了key在內存中的位置了。
B. 用python查詢redis數據,結果中前面為什麼總是有字母b
你好,你是用python3吧,在前面有個b』表示是bytes
解決方法:
#網路www.iwithb.com
importredis
importconfig.configasconf
redis=redis.Redis(host=conf.REDIS_HOST,port=conf.REDIS_PORT,password=conf.REDIS_PASSWORD)
redis.sadd('iwithb',"hello")
url=redis.spop("iwithb")
print(str(url,encoding='utf-8'))
#這樣就沒有b了,注意str(url,encoding='utf-8')
C. python 的 redis 庫,連接池怎麼用
首先要明白redis是一個資料庫redis是一個內存資料庫,所有數據基本上都存在於內存當中,會定時以追加或者快照的方式刷新到硬碟中.由於redis是一個內存資料庫,所以讀取寫入的速度是非常快的,所以經常被用來做數據,頁面等的緩存
D. python3 獲取redis 數據時 為什麼都是 bytes類型
之外,應該都不難理解:三個位元組碼對應了一個漢字,需要直譯器轉譯後才能成為機器碼的中間代碼。位元組碼通常不像源碼一樣可以讓人閱讀,而是編碼後的數值常量,無實際含義,特定平台上的虛擬機器將位元組碼轉譯為可以直接執行的指令。
E. python怎麼將數據寫入到redis
代碼如下:
import redis
class Database:
def __init__(self):
self.host = 'localhost'
self.port = 6379
def write(self,website,city,year,month,day,deal_number):
try:
key = '_'.join([website,city,str(year),str(month),str(day)])
val = deal_number
r = redis.StrictRedis(host=self.host,port=self.port)
r.set(key,val)
except Exception, exception:
print exception
def read(self,website,city,year,month,day):
try:
key = '_'.join([website,city,str(year),str(month),str(day)])
r = redis.StrictRedis(host=self.host,port=self.port)
value = r.get(key)
print value
return value
except Exception, exception:
print exception
if __name__ == '__main__':
db = Database()
db.write('meituan','beijing',2013,9,1,8000)
db.read('meituan','beijing',2013,9,1)
F. python 獲取的redis里的數據怎麼處理
一、獲取所有Key
[python]view plain
#-*-encoding:UTF-8-*-
__author__="Sky"
importredis
pool=redis.ConnectionPool(host='127.0.0.1',port=6379,db=0)
r=redis.StrictRedis(connection_pool=pool)
keys=r.keys()
printtype(keys)
printkeys
運行結果:
<type 'list'>
['fad', '1', '2']
二、獲取所有內容
[python]view plain
importredis
pool=redis.ConnectionPool(host='127.0.0.1',port=6379,db=0)
r=redis.Redis(connection_pool=pool)
pipe=r.pipeline()
pipe_size=100000
len=0
key_list=[]
printr.pipeline()
keys=r.keys()
forkeyinkeys:
key_list.append(key)
pipe.get(key)
iflen<pipe_size:
len+=1
else:
for(k,v)inzip(key_list,pipe.execute()):
printk,v
len=0
key_list=[]
for(k,v)inzip(key_list,pipe.execute()):
printk,v
運行結果:
fad fda
1 e
G. php寫的redis值python能讀么
當然可以了,radis是nosql資料庫,是資料庫的話只要程序可以連接到資料庫都可以獲取到資料庫內的數據
H. 可以使用Python讀取java寫入redis 的object數據,並解析嗎
-redis 本來就只支持存儲一些基本類型(數值,字元...)的。java將對象存儲在redis中是將對象序列化後的位元組數組存入redis的,所以你用python取到的redis中的數據時,會帶有特殊的前綴,表示序列化後java的類信息。java獲取這些數據的時候會有反序列的操作,所以不影響。但python取到數據後是無法解析的。
-Java 存儲與python共享數據時,應避免將String字元串當做對象進行序列化存儲,應直接以字元串的形式存儲,如果需要共享對象,對象轉化為json串存儲。
-另外spring的redisTemplate 進行Hash操作時,就算你存儲的是String類型的數據,也會被當做String對象序列化後存儲。所以 如果過要操作redis的hash結構,建議實例化一個Jedis客戶端進行操作。
I. python 用redis做什麼功能
redis-py提供兩個類Redis和StrictRedis用於實現Redis的命令,StrictRedis用於實現大部分官方的命令,
並使用官方的語法和命令,Redis是StrictRedis的子類,用於向後兼容舊版本的redis-py。
import redis 導入redis模塊,通過python操作redis 也可以直接在redis主機的服務端操作緩存資料庫
r = redis.Redis(host='192.168.19.130', port=6379) host是redis主機,需要redis服務端和客戶端都起著 redis默認埠是6379
r.set('foo', 'Bar') key是"foo" value是"bar" 將鍵值對存入redis緩存
print r.get('foo') Bar 取出鍵foo對應的值!
J. 使用python同步mysql到redis由於數據較多,一條一條讀出來寫到redis太慢,有沒有可以批量操作的。
MYSQL快速同步數據到Redis
舉例場景:存儲游戲玩家的任務數據,游戲伺服器啟動時將mysql中玩家的數據同步到redis中。
從MySQL中將數據導入到Redis的Hash結構中。當然,最直接的做法就是遍歷MySQL數據,一條一條寫入到Redis中。這樣沒什麼錯,但是速度會非常慢。如果能夠想法使得MySQL的查詢輸出數據直接能夠與Redis命令行的輸入數據協議相吻合,可以節省很多消耗和縮短時間。
Mysql資料庫名稱為:GAME_DB, 表結構舉例:
CREATE TABLE TABLE_MISSION (
playerId int(11) unsigned NOT NULL,
missionList varchar(255) NOT NULL,
PRIMARY KEY (playerId)
);
Redis中的數據結構使用哈希表:
鍵KEY為mission, 哈希域為mysql中對應的playerId, 哈希值為mysql中對應的missionList。 數據如下:
[root@iZ23zcsdouzZ ~]# redis-cli
127.0.0.1:6379> hget missions 36598
"{\"10001\":{\"status\":1,\"progress\":0},\"10002\":{\"status\":1,\"progress\":0},\"10003\":{\"status\":1,\"progress\":0},\"10004\":{\"status\":1,\"progress\":0}}"
快速同步方法:
新建一個後綴.sql文件:mysql2redis_mission.sql
內容如下:
SELECT CONCAT(
"*4\r\n",
'$', LENGTH(redis_cmd), '\r\n',
redis_cmd, '\r\n',
'$', LENGTH(redis_key), '\r\n',
redis_key, '\r\n',
'$', LENGTH(hkey), '\r\n',
hkey, '\r\n',
'$', LENGTH(hval), '\r\n',
hval, '\r'
)
FROM (
SELECT
'HSET' as redis_cmd,
'missions' AS redis_key,
playerId AS hkey,
missionList AS hval
FROM TABLE_MISSION
) AS t
創建shell腳本mysql2redis_mission.sh
內容:
mysql GAME_DB --skip-column-names --raw < mission.sql | redis-cli --pipe
Linux系統終端執行該shell腳本或者直接運行該系統命令,即可將mysql資料庫GAME_DB的表TABLE_MISSION數據同步到redis中鍵missions中去。mysql2redis_mission.sql文件就是將mysql數據的輸出數據格式和redis的輸入數據格式協議相匹配,從而大大縮短了同步時間。
經過測試,同樣一份數據通過單條取出修改數據格式同步寫入到redis消耗的時間為5min, 使用上面的sql文件和shell命令,同步完數據僅耗時3s左右。