设计核心数据结构
内存数据库的核心是高效的数据结构。简化版Redis可以使用哈希表(Hash Table)作为基础结构,支持字符串(String)、列表(List)、哈希(Hash)等数据类型。字符串直接存储键值对,列表用双向链表实现,哈希嵌套使用另一个哈希表。
python
class SimpleRedis:
def __init__(self):
self.data = {} # 主字典存储所有数据
self.expires = {} # 过期时间记录
实现基本操作命令
支持基础的SET、GET、DEL等命令。SET操作将键值存入字典,GET从字典检索值,DEL删除键。对于过期时间,使用额外字典记录键的过期时间戳,并在访问时检查是否过期。
python
def set(self, key, value, ex=None):
self.data[key] = value
if ex:
self.expires[key] = time.time() + ex
def get(self, key):
if key in self.expires and time.time() > self.expires[key]:
del self.data[key]
del self.expires[key]
return None
return self.data.get(key)
处理持久化逻辑
简化持久化可通过定时快照实现。将内存数据序列化为JSON或二进制格式写入文件。加载时从文件读取数据重建内存字典。注意处理持久化时的数据一致性。
python
def save(self, filename):
with open(filename, 'w') as f:
json.dump({
'data': self.data,
'expires': self.expires
}, f)
def load(self, filename):
with open(filename) as f:
saved = json.load(f)
self.data = saved['data']
self.expires = saved['expires']
实现网络接口
使用Python的socket模块创建TCP服务器,监听端口并解析客户端命令。命令格式可简化为一行的文本协议,如"SET key value"或"GET key"。通过分拆字符串参数调用对应的数据操作方法。
python
def handle_client(conn, redis):
while True:
cmd = conn.recv(1024).decode().strip().split()
if not cmd:
break
if cmd[0] == 'SET':
redis.set(cmd[1], cmd[2])
conn.send(b'OK')
elif cmd[0] == 'GET':
val = redis.get(cmd[1])
conn.send(str(val).encode())
性能优化思路
使用事件循环(如select模块)处理多客户端连接,避免阻塞。对于高频操作的关键路径,如哈希表查找,可用Python内置的dict优化。过期键的清理可采用惰性删除(访问时检查)结合定期扫描的策略。
例如:
gitee.com/huang-yong55/liusir/blob/master/bi.md
gitee.com/huang-yong55/liusir/blob/master/er.md
gitee.com/huang-yong55/liusir/blob/master/q10.md
gitee.com/huang-yong55/liusir/blob/master/q4.md
gitee.com/huang-yong55/liusir/blob/master/qw.md
gitee.com/huang-yong55/liusir/blob/master/zx1.md
gitee.com/huang-yong55/liusir/blob/master/zx2.md
gitee.com/huang-yong55/liusir/blob/master/zx3.md
gitee.com/huang-yong55/liusir/blob/master/zx4.md
gitee.com/huang-yong55/liusir/blob/master/zx5.md
python
def start_server(host, port):
redis = SimpleRedis()
with socket.socket() as s:
s.bind((host, port))
s.listen()
while True:
conn, _ = s.accept()
handle_client(conn, redis)