无法通过Python连接到在Azure Linux VM上运行的Redis实例

时间:2018-11-19 22:10:33

标签: python azure redis redis-py

我在Azure上创建了Ubuntu VM。在其入站网络过滤器中,我添加了端口 22 (用于 SSH ing)和 6379 (用于Redis)。然后,我从我的bash shell SSH 进入一个实例,从源代码下载,构建和安装Redis。生成的redis.conf文件位于/tmp/redis-stable中,因此我对其进行了编辑以注释掉bind 127.0.0.1规则。

然后我从redis-server redis.conf目录启动/tmp/redis-stable,然后正常启动,接着我 SSH 进入另一个VM实例,启动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 0.0.0.0行之后,我还尝试在redis.conf文件中添加bind 127.0.0.1。结果相同。

更新:我尝试在配置文件中将保护模式设置为no,然后在VM中运行sudo ufw allow 6379。结果还是一样。但是现在运行redis-server redis.conf时出现一个奇怪的错误。我没有得到显示为数字的典型redis多维数据集,而是得到了这一点:

enter image description here

此后,如果我输入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连接。

1 个答案:

答案 0 :(得分:1)

我尝试在Azure上创建Ubuntu VM,从源代码构建和配置Redis服务器,并在Azure门户上为我的VM NSG添加端口规则,然后我通过相同的代码将Redis服务器成功连接到python redis软件包

这是我的步骤,如下所示。

  1. 在Azure门户上创建Ubuntu 18.04 VM。
  2. 通过SSH连接Ubuntu VM以安装构建软件包(包括build-essentialgccmake),从以下位置下载并解压缩redis源代码的tar.gz文件redis.io,并使用makemake test构建并测试Redis服务器。
  3. 通过redis.conf配置vim,将bind的配置从127.0.0.1更改为0.0.0.0
  4. 在Azure门户上我的VM的标签6379中显示的Network Interface中,将带有TCP的Settings -> Networking端口的新端口规则添加到NSG中,如下图。 li>

enter image description here 注意:我的Networking标签中有两个NSG,第二个与我的Network Interface有关,可以通过Internet进行访问。 enter image description hereenter image description here 5.通过redis在本地计算机上安装pip install redis。 6.打开一个终端以键入python,以尝试连接托管在我的Azure Ubuntu VM上的Redis服务器,并成功获取foo密钥的值。

>>> import redis
>>> r = redis.Redis(host='xxx.xx.xx.xxx')
>>> r.get('foo')
b'bar'

我在测试中发现了两个关键问题。

  1. 对于redis.conf,绑定主机必须为0.0.0.0。否则,redis服务器将以保护模式运行以拒绝查询。
  2. 对于NSG端口规则,请确保在NSG中添加的新端口规则已附加到当前网络接口,而不是默认子网。
  3. python软件包redis是惰性评估,仅在发生第一个命令请求时才连接redis服务器。

希望有帮助。