如何在python中有效地启动和停止redis服务器?

2g32fytz  于 2023-08-02  发布在  Redis
关注(0)|答案(1)|浏览(196)

我需要在我的UT(单元测试)代码中启动redis服务器,这是用python编写的,一旦完成就停止它,这是在多个UT中完成的。但是我看到停止redis服务器部分不能正常工作,因为当redis服务器启动在下一个UT中触发时,它会失败,并显示Address already in Use错误。而停止也失败了。
当停止后再次调用start函数时。看到下面的错误。5638:M 2023年7月1日07:09:12.828 * 单调时钟:POSIX clock_gettime 5638:M 2023年7月1日07:09:12.828 #警告:无法创建服务器TCP侦听套接字 *:6379:bind:Address already in use 5638:M 01 Jul 2023 07:09:12.828 #在端口6379(TCP)上侦听失败,正在中止。5632:信号处理程序(1688195360)接收到SIGTERM调度关闭... 5632:M 01 Jul 2023 07:09:20.844 #用户请求关闭... 5632:M 2023年7月1日07:09:20.844 * 退出前保存最终RDB快照。5632:M 01 Jul 2023 07:09:20.849 * 数据库已保存在磁盘5632:M 01 Jul 2023 07:09:20.849 # Redis is is now ready to exit,bye bye...
如果我使用netstat,我看到一些TIME_WAIT连接仍然可见,这可能是早期启动失败的原因?
下面是代码:

class DBServer(object):
    def __init__(self):
        super().__init__()
        self.terminate = False
        self.__initialize_db()

    def __del__(self):
        self.terminate = True
        self.db_server.terminate()
        try:
            self.db_server.wait(timeout=10)
        except subprocess.TimeoutExpired as e:
            print("%s" % e)
        finally:
            self.db_server.kill()

    def __update_dns_entry(self):
        try:
            with open("/etc/hosts", "r+") as f:
                content = f.readlines()
                for l in content:
                    if "redis" in l:
                        return
                f.seek(0, 2)
                f.write("\n127.0.0.1\tredis")
        except:
            print("Exception occurred while trying to update /etc/hosts file %s" % traceback.format_exc())
            os.exit()

    def __initialize_db(self):
        self.__update_dns_entry()
        self.db_server = subprocess.Popen(
                ["/usr/bin/redis-server",], 
                close_fds=True)

    
    def start(self):
        time.sleep(5)
        self.add_db_entries()
        self.tid = threading.Thread(target=self.run)
        self.tid.start()

    def run(self):
        while not self.terminate:
            time.sleep(1)

    def stop(self):
        self.terminate = True
        redis_conn = redis.Redis(host = "redis", port = 6379, db=os.environ["DB"])
        redis_conn.flushall()
        self.tid.join()
        time.sleep(3)

字符串

oxiaedzo

oxiaedzo1#

停止redis的正确方法是调用SHUTDOWN命令,而不是杀死/终止正在运行Redis的进程
虽然你没有提到它,但从你的代码来看,你似乎正在使用redis-py,其中关闭redis的命令是:

redis_conn.shutdown()

字符串
使用redis-py关闭的完整文档在这里

相关问题