2016-02-29 87 views
4

我想加载大量的数据到memcachedb。 我正在MySQL数据库上运行一些查询,并且我想将这些查询的结果存储在memcachedb中以便以后轻松访问。正确的方式来加载批量数据

目前,我只是使用简单的set命令将结果存储在memcachedb中,但由于存在数十亿个这样的结果,因此将它们逐个存储在循环中效率非常低并且非常耗时。所以,我想知道是否有更好的方式将数据加载到memcachedb?就像传统RDMS中的数据导入向导一样

我正在使用pylibmc连接到memcachedb。

回答

4

的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; 

不确定这实际上更快,但我怀疑它是。

+0

是的,我发现multi_set函数,比个别设置更好,但我一直在寻找更像memcachedb(数据库)可用的批量导入功能。我现在正在使用multi_set。 – Wajahat

+0

@Wajahat我不确定你的意思是“批量导入功能”?如果你正在寻找一个'import_my_four_billion_keys_from_mysql_efficiently()'函数,那么AFAIK并不是真的存在,但你可以像概述那样很容易地创建一个... – Carpetsmoker

相关问题