无法从 Python 连接到 Azure Linux VM 上的 Redis 实例 运行
Unable to connect to Redis instance running on Azure Linux VM from Python
我在 Azure 上创建了一个 Ubuntu 虚拟机。在其入站网络过滤器中,我添加了端口 22(用于 SSHing)和 6379(用于 Redis ).在此之后,我 SSH 从我的 bash shell 进入一个实例,从源代码下载、构建和安装 Redis。生成的 redis.conf
文件位于 /tmp/redis-stable
,因此我对其进行了编辑以注释掉 bind 127.0.0.1
规则。
然后我从/tmp/redis-stable
目录启动redis-server redis.conf
,启动正常,然后我SSH进入另一个虚拟机实例,启动redis-cli
并设置一些键。取回它们,工作正常。
现在 Python 我正在 运行 执行此命令:
r = redis.Redis(host='same_which_I_use_for_SSHing', port=6379, password='pwd')
它立即连接(看起来很奇怪)。但是当我尝试像 r.get("foo")
这样的简单命令时,我得到了这个错误:
>>> r.get("foo")
Traceback (most recent call last):
File "/lib/python3.5/site-packages/redis/connection.py", line 484, in connect
sock = self._connect()
File "/lib/python3.5/site-packages/redis/connection.py", line 511, in _connect
socket.SOCK_STREAM):
File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/socket.py", line 732, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno 8] nodename nor servname provided, or not known
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/lib/python3.5/site-packages/redis/client.py", line 667, in execute_command
connection.send_command(*args)
File "/lib/python3.5/site-packages/redis/connection.py", line 610, in send_command
self.send_packed_command(self.pack_command(*args))
File "/lib/python3.5/site-packages/redis/connection.py", line 585, in send_packed_command
self.connect()
File "/lib/python3.5/site-packages/redis/connection.py", line 489, in connect
raise ConnectionError(self._error_message(e))
redis.exceptions.ConnectionError: Error 8 connecting to username@ip_address. nodename nor servname provided, or not known.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/lib/python3.5/site-packages/redis/connection.py", line 484, in connect
sock = self._connect()
File "/lib/python3.5/site-packages/redis/connection.py", line 511, in _connect
socket.SOCK_STREAM):
File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/socket.py", line 732, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno 8] nodename nor servname provided, or not known
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/lib/python3.5/site-packages/redis/client.py", line 976, in get
return self.execute_command('GET', name)
File "/lib/python3.5/site-packages/redis/client.py", line 673, in execute_command
connection.send_command(*args)
File "/lib/python3.5/site-packages/redis/connection.py", line 610, in send_command
self.send_packed_command(self.pack_command(*args))
File "/lib/python3.5/site-packages/redis/connection.py", line 585, in send_packed_command
self.connect()
File "/lib/python3.5/site-packages/redis/connection.py", line 489, in connect
raise ConnectionError(self._error_message(e))
redis.exceptions.ConnectionError: Error 8 connecting to username@ip_address. nodename nor servname provided, or not known.
知道如何解决这个问题吗?仅供参考,错误消息中的 username@ip_address
与我分别从 bash 用于 SSH 和从 Python 连接到 Redis 相同:
ssh username@ip_address
r = redis.Redis(host='username@ip_address', port=6379, password='pwd')
我还尝试在注释掉 bind 127.0.0.1
行后在 redis.conf
文件中添加 bind 0.0.0.0
。同样的结果。
更新:我尝试在配置文件中将保护模式设置为 no,然后在 VM 中设置 运行ning sudo ufw allow 6379
。还是一样的结果。但是现在当我 运行 redis-server redis.conf
时我得到了一个奇怪的错误。我没有得到显示为图形的典型 redis 多维数据集相反,我得到了这个:
在此之后,如果我输入 redis-cli
并发出像 set foo boo
这样的简单命令,我会收到此错误消息:
127.0.0.1:6379> set foo 1
(error) MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on disk. Commands that may modify the data set are disabled, because this instance is configured to report errors during writes if RDB snapshotting fails (stop-writes-on-bgsave-error option). Please check the Redis logs for details about the RDB error.
此后甚至关机失败。我必须 运行 grep
找到 redis-server 的进程并手动杀死它,然后 redis-server
命令需要 运行 正常启动它。但当然,我仍然无法从远程连接 Mac.
我尝试在 Azure 上创建一个 Ubuntu VM,从源代码构建和配置 redis 服务器,并在 Azure 门户上为我的 VM NSG 添加端口规则,然后我通过相同的方式连接了 redis 服务器python redis 包代码成功。
下面是我的步骤。
- 在 Azure 门户上创建 Ubuntu 18.04 VM。
- 通过 SSH 连接 Ubuntu VM 以安装构建包(包括
build-essential
、gcc
和 make
),下载并解压缩 tar.gz
来自 redis.io
的 redis 源代码文件,并使用 make
& make test
. 构建和测试 redis 服务器
- 通过
vim
配置 redis.conf
,将 bind
配置从 127.0.0.1
更改为 0.0.0.0
。
- 为我在 Azure 门户上的 VM 的选项卡
Settings -> Networking
中显示的 Network Interface
添加带有 TCP 的 6379
端口的新端口规则,如下图所示。
注意:在我的Networking
选项卡中有两个NSG,第二个与我的Network Interface
相关,可以通过互联网访问。
和
5. 在我的本地机器上通过 pip install redis
安装 redis
。
6. 打开终端输入 python
尝试连接托管在我的 Azure Ubuntu VM 上的 redis 服务器并成功获取 foo
键的值。
>>> import redis
>>> r = redis.Redis(host='xxx.xx.xx.xxx')
>>> r.get('foo')
b'bar'
我在测试中发现了两个关键问题。
- 对于
redis.conf
,绑定主机必须是0.0.0.0
。如果不是,redis 服务器将运行处于保护模式以拒绝查询。
- 对于 NSG 端口规则,请确保在附加到当前网络接口的 NSG 中添加的新端口规则,而不是默认子网。
- python包
redis
是惰性评估,只有在第一个命令请求发生时才连接redis服务器。
希望对您有所帮助。
我在 Azure 上创建了一个 Ubuntu 虚拟机。在其入站网络过滤器中,我添加了端口 22(用于 SSHing)和 6379(用于 Redis ).在此之后,我 SSH 从我的 bash shell 进入一个实例,从源代码下载、构建和安装 Redis。生成的 redis.conf
文件位于 /tmp/redis-stable
,因此我对其进行了编辑以注释掉 bind 127.0.0.1
规则。
然后我从/tmp/redis-stable
目录启动redis-server redis.conf
,启动正常,然后我SSH进入另一个虚拟机实例,启动redis-cli
并设置一些键。取回它们,工作正常。
现在 Python 我正在 运行 执行此命令:
r = redis.Redis(host='same_which_I_use_for_SSHing', port=6379, password='pwd')
它立即连接(看起来很奇怪)。但是当我尝试像 r.get("foo")
这样的简单命令时,我得到了这个错误:
>>> r.get("foo")
Traceback (most recent call last):
File "/lib/python3.5/site-packages/redis/connection.py", line 484, in connect
sock = self._connect()
File "/lib/python3.5/site-packages/redis/connection.py", line 511, in _connect
socket.SOCK_STREAM):
File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/socket.py", line 732, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno 8] nodename nor servname provided, or not known
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/lib/python3.5/site-packages/redis/client.py", line 667, in execute_command
connection.send_command(*args)
File "/lib/python3.5/site-packages/redis/connection.py", line 610, in send_command
self.send_packed_command(self.pack_command(*args))
File "/lib/python3.5/site-packages/redis/connection.py", line 585, in send_packed_command
self.connect()
File "/lib/python3.5/site-packages/redis/connection.py", line 489, in connect
raise ConnectionError(self._error_message(e))
redis.exceptions.ConnectionError: Error 8 connecting to username@ip_address. nodename nor servname provided, or not known.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/lib/python3.5/site-packages/redis/connection.py", line 484, in connect
sock = self._connect()
File "/lib/python3.5/site-packages/redis/connection.py", line 511, in _connect
socket.SOCK_STREAM):
File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/socket.py", line 732, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno 8] nodename nor servname provided, or not known
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/lib/python3.5/site-packages/redis/client.py", line 976, in get
return self.execute_command('GET', name)
File "/lib/python3.5/site-packages/redis/client.py", line 673, in execute_command
connection.send_command(*args)
File "/lib/python3.5/site-packages/redis/connection.py", line 610, in send_command
self.send_packed_command(self.pack_command(*args))
File "/lib/python3.5/site-packages/redis/connection.py", line 585, in send_packed_command
self.connect()
File "/lib/python3.5/site-packages/redis/connection.py", line 489, in connect
raise ConnectionError(self._error_message(e))
redis.exceptions.ConnectionError: Error 8 connecting to username@ip_address. nodename nor servname provided, or not known.
知道如何解决这个问题吗?仅供参考,错误消息中的 username@ip_address
与我分别从 bash 用于 SSH 和从 Python 连接到 Redis 相同:
ssh username@ip_address
r = redis.Redis(host='username@ip_address', port=6379, password='pwd')
我还尝试在注释掉 bind 127.0.0.1
行后在 redis.conf
文件中添加 bind 0.0.0.0
。同样的结果。
更新:我尝试在配置文件中将保护模式设置为 no,然后在 VM 中设置 运行ning sudo ufw allow 6379
。还是一样的结果。但是现在当我 运行 redis-server redis.conf
时我得到了一个奇怪的错误。我没有得到显示为图形的典型 redis 多维数据集相反,我得到了这个:
在此之后,如果我输入 redis-cli
并发出像 set foo boo
这样的简单命令,我会收到此错误消息:
127.0.0.1:6379> set foo 1
(error) MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on disk. Commands that may modify the data set are disabled, because this instance is configured to report errors during writes if RDB snapshotting fails (stop-writes-on-bgsave-error option). Please check the Redis logs for details about the RDB error.
此后甚至关机失败。我必须 运行 grep
找到 redis-server 的进程并手动杀死它,然后 redis-server
命令需要 运行 正常启动它。但当然,我仍然无法从远程连接 Mac.
我尝试在 Azure 上创建一个 Ubuntu VM,从源代码构建和配置 redis 服务器,并在 Azure 门户上为我的 VM NSG 添加端口规则,然后我通过相同的方式连接了 redis 服务器python redis 包代码成功。
下面是我的步骤。
- 在 Azure 门户上创建 Ubuntu 18.04 VM。
- 通过 SSH 连接 Ubuntu VM 以安装构建包(包括
build-essential
、gcc
和make
),下载并解压缩tar.gz
来自redis.io
的 redis 源代码文件,并使用make
&make test
. 构建和测试 redis 服务器
- 通过
vim
配置redis.conf
,将bind
配置从127.0.0.1
更改为0.0.0.0
。 - 为我在 Azure 门户上的 VM 的选项卡
Settings -> Networking
中显示的Network Interface
添加带有 TCP 的6379
端口的新端口规则,如下图所示。
Networking
选项卡中有两个NSG,第二个与我的Network Interface
相关,可以通过互联网访问。
pip install redis
安装 redis
。
6. 打开终端输入 python
尝试连接托管在我的 Azure Ubuntu VM 上的 redis 服务器并成功获取 foo
键的值。
>>> import redis
>>> r = redis.Redis(host='xxx.xx.xx.xxx')
>>> r.get('foo')
b'bar'
我在测试中发现了两个关键问题。
- 对于
redis.conf
,绑定主机必须是0.0.0.0
。如果不是,redis 服务器将运行处于保护模式以拒绝查询。 - 对于 NSG 端口规则,请确保在附加到当前网络接口的 NSG 中添加的新端口规则,而不是默认子网。
- python包
redis
是惰性评估,只有在第一个命令请求发生时才连接redis服务器。
希望对您有所帮助。