我有一個在傳統的appengine 2.7中運行的游戲服務器。 我已經將服務器遷移到了 py3/flask 和所有其他部分。 我讓新的服務器連接到一個 Redis 實體,而舊的服務器則使用 py2.7 的 memcache。
我正在考慮將 2.7 版本的服務器連接到 Redis 的 memcache,因為我已經將它作為一個階段性遷移來運行。 這樣我就可以在 py3 服務器和 py2 服務器之間分配流量,并且它們將在我測驗時使用同一個 memcache 服務器。我可以讓一些測驗用戶與新的服務器對話,并與當前的服務器共存。
我已經有一個版本的 py2.7 服務器與 Redis 對話......但是我發現關于使用 Redis 來存盤 ndb 模型的檔案有點令人困惑。我似乎不能像在舊有的 memcache 中那樣直接在 Redis 中填充一個 ndb 模型類。
在遷移檔案中,您可以將 Redis 設定為 appengine 的 "全域快取",具體例子如下:
client = ndb.Client()
global_cache = ndb.RedisCache.from_environment()
with client.context(global_cache=global_cache)。
books = Book.query()
for book in books:
print(book.to_dict() )
我不太清楚這意味著什么。我是否需要以這種方式構建我希望快取的所有查詢,或者是否需要進行一次性設定,然后模型將自動快取? 如果存在快取,上述示例是否會自動從快取中提取?
目前在傳統的memcache服務器中,我收集了一堆模型實體(或者在我的案例中,某個用戶是其中的成員的游戲)到一個python串列中,并用一個鍵來快取它們
cacheKey = userskey.urlsafe() "_gamesList"
每當這個用戶的游戲以某種方式被改變時(更新、洗掉、添加......等等),我就會洗掉cacheKey。下次這個用戶查詢他們的游戲串列時,我就會重建快取。看起來我不能在Redis中簡單地存盤這樣的資料。另外,由于該用戶與服務器的互動次數較多,我只想讓代表該用戶的模型被快取起來。每次該用戶與我的服務器交談時,我都需要用密鑰來呼叫他們的用戶賬戶
。我想我只是對全域快取感到困惑,以及這一切與傳統的memcache有什么不同。 目前,我使用傳統的memcache獲得了接近90%的快取點擊率,所以當然值得嘗試用Redis來復制。 即使只是提供一個實用的例子,也會有幫助。令人驚訝的是,我在周圍的搜索中并沒有發現這個問題。
uj5u.com熱心網友回復:
"全域快取 "這個術語有點令人困惑,它只是意味著MemoryStore Redis實體可以從你的專案之外訪問。 如果你想繼續使用NDB,你需要先遷移到CloudNDB。為了回答你的一個問題--MemoryStore沒有自動快取功能。
然而,我的建議是--如果你所做的只是在Redis中存盤鍵值對,為什么不直接使用本地Redis功能呢?
# Connect to Redis (I create a CloudDNS record which points to the private IP)
pool = redis.ConnectionPool(host=<REDIS_HOST>, port=<REDIS_PORT> , db=0)
r = redis.Redis(connection_pool=pool)
然后你可以以位元組的形式獲取和設定物件
import pickle, io
f = io.BytesIO()
pickle.dump(book.to_dict(),f)
f.seek(0)
res = r.set(alias,f.read() )
# res將是True或False。
outObj = r.get(alias)
if len(outObj) > 0:
dictObj = pickle.load(outObj)
else:
# Cache Miss - get it from the DB and store it in Redis.
另外MemoryStore很貴,我使用FakeRedis在本地進行測驗
。import fakeredis as redis
serv = redis.FakeServer()
r = redis.FakeStrictRedis(server=serv)
更新 - 從你關于 UnicodeDecodeError 的評論中,我不知道你的字典里有什么資料導致了問題,你可以嘗試轉換為 json,對于任何不可序列化的東西(如日期時間物件),只需將它們轉換為 str
。jsonObj = json.dumps(dictObj, default=str)
f = io.BytesIO()
pickle.dump(jsonObj,f)
f.seek(0)
uj5u.com熱心網友回復:
正如rossco所提到的,Memorystore Redis中沒有自動快取。在Legacy Memcache中,快取是全域的,并且默認情況下在應用程式的前端、后端以及其所有服務和版本中共享。GlobalCache介面有相同的描述。然而,也有一些不同之處,比如一個RedisCache物件(它是GlobalCache的一個實作)被創建并傳遞給客戶端背景關系,從你提供的例子中可以看出,這與你創建一個Legacy Memcache客戶端的方式相反。關于暴露的方法,也有一些區別,可以在以下檔案中看到。
一旦客戶端背景關系被初始化,所有使用該背景關系的操作將使用單一的全域快取物件。使用相同的 global_cache 構建多個背景關系,或使用依賴注入來傳遞相同的背景關系,將是一次性的設定。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/317565.html
標籤:
