我想加載大量的數據到memcachedb。 我正在MySQL數據庫上運行一些查詢,並且我想將這些查詢的結果存儲在memcachedb中以便以後輕鬆訪問。正確的方式來加載批量數據
目前,我只是使用簡單的set命令將結果存儲在memcachedb中,但由於存在數十億個這樣的結果,因此將它們逐個存儲在循環中效率非常低並且非常耗時。所以,我想知道是否有更好的方式將數據加載到memcachedb?就像傳統RDMS中的數據導入嚮導一樣
我正在使用pylibmc連接到memcachedb。
我想加載大量的數據到memcachedb。 我正在MySQL數據庫上運行一些查詢,並且我想將這些查詢的結果存儲在memcachedb中以便以後輕鬆訪問。正確的方式來加載批量數據
目前,我只是使用簡單的set命令將結果存儲在memcachedb中,但由於存在數十億個這樣的結果,因此將它們逐個存儲在循環中效率非常低並且非常耗時。所以,我想知道是否有更好的方式將數據加載到memcachedb?就像傳統RDMS中的數據導入嚮導一樣
我正在使用pylibmc連接到memcachedb。
的pylibmc庫具有set_multi
功能,發送一串命令一氣呵成:
mc.set_multi({
'key': 'Hello',
'another': True,
#[..]
})
這也許應該工作不夠好。如果你有密鑰的數十億,你可能想把它分成幾千塊。
如果您只是通過套接字發送命令,您可能會擠出更多的性能。 memcache protocol 非常簡單。這樣做的好處是您可以添加noreply
標誌,這樣服務器就不會麻煩發送回覆。當然,這意味着你不能做任何錯誤檢查,並且無論出於何種原因丟失幾個鍵都是可以的。
這裏是概念的一個簡單證明:
#!/usr/bin/env python
import socket
data = 'set key_1 0 86400 5\r\nabcde\r\n'
data += 'set key_2 0 86400 5\r\nzxcvb\r\n'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 11211))
s.sendall(data)
print(s.recv(8192))
s.close()
# Verify if it worked!
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 11211))
s.sendall('get key_1\r\n')
s.sendall('get key_2\r\n')
print(s.recv(8192))
s.close()
應該輸出:
STORED
STORED
VALUE key_1 0 5
abcde
END
VALUE key_2 0 5
zxcvb
END
的set
命令的格式是:
set <key> <flags> <exptime> <data_size> [noreply]\r\n
<data>\r\n
當然,這只是一個概念證明;一個更高級的例子可能是這樣的:
#!/usr/bin/env python
import socket
def make_set(n, data):
return 'set key_{} 0 86400 {}\r\n{}\r\n'.format(n, len(data), data)
data = open('/etc/aliases').readlines()
commands = [ make_set(n, d.strip()) for n, d in enumerate(data) if d.strip() != '' ]
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 11211))
s.sendall(''.join(commands))
print(s.recv(65000))
# Verify if it worked!
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 11211))
for n in range(0, len(commands)):
s.sendall('get key_{}\r\n'.format(n))
print(s.recv(65000))
s.close()
如果你從MySQL中獲取數據,然後再考慮做與SQL查詢set
命令!例如:
select
concat('set key_', page_id, ' 0 86400 ', length(page_title), '\r\n', page_title, '\r\n')
as cmd
from page limit 2;
不確定這實際上更快,但我懷疑它是。
是的,我發現multi_set函數,比個別設置更好,但我一直在尋找更像memcachedb(數據庫)可用的批量導入功能。我現在正在使用multi_set。 – Wajahat
@Wajahat我不確定你的意思是「批量導入功能」?如果你正在尋找一個'import_my_four_billion_keys_from_mysql_efficiently()'函數,那麼AFAIK並不是真的存在,但你可以像概述那樣很容易地創建一個... – Carpetsmoker