鱼C论坛

 找回密码
 立即注册
查看: 149|回复: 3

[已解决]python连接Cassandra数据库

[复制链接]
发表于 2024-10-17 21:02:05 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
我希望在python爬虫项目中使用Cassandra数据库,当我使用如下代码时,生成的log文件显示连接被主机拒绝,但同时又能成功将数据库中的表名读取出来


from cassandra.cluster import Cluster

class CassandraDatabase():
    def __init__(self, keyspace, table, host=['localhost'], port=9042):
        self.keyspace = keyspace
        self.host = host
        self.table = table
        self.port = port

        self.connect()

    def __del__(self,):
        self.cluster.shutdown()

    def connect(self,):
        self.cluster = Cluster(contact_points=self.host, port=self.port, protocol_version=4)
        self.session = self.cluster.connect()

        keyspace_name = 'mykeyspacetest'

        # 获取集群的元数据
        metadata = self.session.cluster.metadata

        # 通过keyspace名称获取具体的keyspace元数据
        keyspace_metadata = metadata.keyspaces[keyspace_name]

        # 获取该keyspace中的所有表名
        table_names = keyspace_metadata.tables.keys()

        # 打印表名
        print("Keyspace '{}' 中的表名:".format(keyspace_name))
        for table_name in table_names:
            print(table_name)

        self.create_keyspace()
        self.session.set_keyspace(self.keyspace)

    def close(self,):
        self.cluster.shutdown()

log文件中的报错信息如下:
2024-10-17 20:25:57 [cassandra.cluster] WARNING: Cluster.__init__ called with contact_points specified, but no load_balancing_policy. In the next major version, this will raise an error; please specify a load-balancing policy. (contact_points = ['localhost'], lbp = None)2024-10-17 20:25:59 [cassandra.cluster] WARNING: [control connection] Error connecting to ::1:9042:Traceback (most recent call last):  File "D:\Anaconda\envs\datataiwanpy38\lib\site-packages\cassandra\cluster.py", line 3577, in _reconnect_internal    return self._try_connect(host)  File "D:\Anaconda\envs\datataiwanpy38\lib\site-packages\cassandra\cluster.py", line 3599, in _try_connect    connection = self._cluster.connection_factory(host.endpoint, is_control_connection=True)  File "D:\Anaconda\envs\datataiwanpy38\lib\site-packages\cassandra\cluster.py", line 1670, in connection_factory    return self.connection_class.factory(endpoint, self.connect_timeout, *args, **kwargs)  File "D:\Anaconda\envs\datataiwanpy38\lib\site-packages\cassandra\connection.py", line 846, in factory    conn = cls(endpoint, *args, **kwargs)  File "D:\Anaconda\envs\datataiwanpy38\lib\site-packages\cassandra\io\asyncorereactor.py", line 353, in __init__    self._connect_socket()  File "D:\Anaconda\envs\datataiwanpy38\lib\site-packages\cassandra\connection.py", line 951, in _connect_socket    raise socket.error(sockerr.errno, "Tried connecting to %s. Last error: %s" %ConnectionRefusedError: [Errno 10061] Tried connecting to [('::1', 9042, 0, 0)]. Last error: 由于目标计算机积极拒绝,无法连接。


同时,Cassandra数据库端的日志输出有:
INFO  [nioEventLoopGroup-2-6] 2024-10-17 20:49:14,872 Message.java:687 - Unexpected exception during request; channel = [id: 0x063be996, L:/127.0.0.1:9042 - R:/127.0.0.1:24261]java.io.IOException: 远程主机强迫关闭了一个现有的连接。
我已经尝试使用:

1. 修改连接方法中的协议版本,改为protocol_version=4
2. 修改localhost为127.0.0.1,怀疑是回访地址为::1的问题





最佳答案
2024-10-17 21:02:22
根据你提供的信息和你的尝试,你已做了一些努力来解决问题。以下是一些可能的原因与解决方案:

1. **确保参数正确**:
   - 确保初始化`CassandraDatabase`时传入了有效的`host`。如果没有,Python中默认的值将为`None`,这会导致连接被拒绝。
   - 确保编程时将`host`设置为有效的Cassandra节点地址,如`127.0.0.1`而不是`localhost`。

2. **检查Cassandra的网络配置**:
   - 确保Cassandra配置文件`cassandra.yaml`中的`rpc_address`正确设置为`0.0.0.0`或`127.0.0.1`,允许本地连接。
   - 确保`listen_address`正确配置。

3. **防火墙或安全组设置**:
   - 确保没有防火墙或安全组阻止Cassandra的9042端口。
   - 本地防火墙设置可以通过命令行工具如`ufw`(在Unix系统中)或Windows防火墙设置界面进行调整。

4. **Cassandra运行状况**:
   - 确保Cassandra服务正在运行且没有错误。
   - 使用`nodetool status`命令检查集群状态。

5. **日志输出和调试**:
   - 查看更多Cassandra日志以查明是否还有其他错误信息。
   - 确认Python客户端包(如`cassandra-driver`)的版本兼容于当前的Cassandra版本。

6. **检查Python代码**:
   - 你的代码示例中`keyspace_metadata.tables.keys()`可能会抛出错误,因为应使用`keyspace_metadata[keyspace_name].tables.keys()`来获取指定keyspace中的表名。
   - 确保在实际使用代码时替换了任何占位符(如`self.host`, `self.keyspace`等)为实际值。

尝试解决这些问题,如果连接问题仍然发生,建议在不同的环境中验证,包括数据库配置和代码逻辑。这样可以更好地隔离问题所在。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-10-17 21:02:22 | 显示全部楼层    本楼为最佳答案   
根据你提供的信息和你的尝试,你已做了一些努力来解决问题。以下是一些可能的原因与解决方案:

1. **确保参数正确**:
   - 确保初始化`CassandraDatabase`时传入了有效的`host`。如果没有,Python中默认的值将为`None`,这会导致连接被拒绝。
   - 确保编程时将`host`设置为有效的Cassandra节点地址,如`127.0.0.1`而不是`localhost`。

2. **检查Cassandra的网络配置**:
   - 确保Cassandra配置文件`cassandra.yaml`中的`rpc_address`正确设置为`0.0.0.0`或`127.0.0.1`,允许本地连接。
   - 确保`listen_address`正确配置。

3. **防火墙或安全组设置**:
   - 确保没有防火墙或安全组阻止Cassandra的9042端口。
   - 本地防火墙设置可以通过命令行工具如`ufw`(在Unix系统中)或Windows防火墙设置界面进行调整。

4. **Cassandra运行状况**:
   - 确保Cassandra服务正在运行且没有错误。
   - 使用`nodetool status`命令检查集群状态。

5. **日志输出和调试**:
   - 查看更多Cassandra日志以查明是否还有其他错误信息。
   - 确认Python客户端包(如`cassandra-driver`)的版本兼容于当前的Cassandra版本。

6. **检查Python代码**:
   - 你的代码示例中`keyspace_metadata.tables.keys()`可能会抛出错误,因为应使用`keyspace_metadata[keyspace_name].tables.keys()`来获取指定keyspace中的表名。
   - 确保在实际使用代码时替换了任何占位符(如`self.host`, `self.keyspace`等)为实际值。

尝试解决这些问题,如果连接问题仍然发生,建议在不同的环境中验证,包括数据库配置和代码逻辑。这样可以更好地隔离问题所在。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-10-23 16:51:52 | 显示全部楼层
更新:
我将连接代码
self.cluster = Cluster(contact_points=self.host, port=self.port, protocol_version=4)
修改为:
self.cluster = Cluster(['localhost'])
能连接上了,但log文件里还是会有
[cassandra.cluster] WARNING: Cluster.__init__ called with contact_points specified, but no load_balancing_policy. In the next major version, this will raise an error; please specify a load-balancing policy. (contact_points = ['localhost'], lbp = None)2024-10-17 20:25:59 [cassandra.cluster] WARNING: [control connection] Error connecting to ::1:9042:Traceback (most recent call last):  File "D:\Anaconda\envs\datataiwanpy38\lib\site-packages\cassandra\cluster.py", line 3577, in _reconnect_internal    return self._try_connect(host)  File "D:\Anaconda\envs\datataiwanpy38\lib\site-packages\cassandra\cluster.py", line 3599, in _try_connect    connection = self._cluster.connection_factory(host.endpoint, is_control_connection=True)  File "D:\Anaconda\envs\datataiwanpy38\lib\site-packages\cassandra\cluster.py", line 1670, in connection_factory    return self.connection_class.factory(endpoint, self.connect_timeout, *args, **kwargs)  File "D:\Anaconda\envs\datataiwanpy38\lib\site-packages\cassandra\connection.py", line 846, in factory    conn = cls(endpoint, *args, **kwargs)  File "D:\Anaconda\envs\datataiwanpy38\lib\site-packages\cassandra\io\asyncorereactor.py", line 353, in __init__    self._connect_socket()  File "D:\Anaconda\envs\datataiwanpy38\lib\site-packages\cassandra\connection.py", line 951, in _connect_socket    raise socket.error(sockerr.errno, "Tried connecting to %s. Last error: %s" %ConnectionRefusedError: [Errno 10061] Tried connecting to [('::1', 9042, 0, 0)]. Last error: 由于目标计算机积极拒绝,无法连接。
不过出现的时间较靠后
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-10-23 17:03:59 | 显示全部楼层
pangforFC 发表于 2024-10-23 16:51
更新:
我将连接代码
self.cluster = Cluster(cont ...


看起来你现在能连接,但仍收到警告。可以考虑以下几点:

1. **指定`contact_points`和`load_balancing_policy`**:
   你可以明确指定Cassandra节点,例:
from cassandra.policies import RoundRobinPolicy

   self.cluster = Cluster(
       contact_points=['127.0.0.1'],
       port=9042,
       load_balancing_policy=RoundRobinPolicy()
   )
   这样消除没有指定负载均衡策略的警告。

2. **检查IPv6配置**:
   错误信息中提到连接`::1`,这是IPv6的本地主机地址。如果你不使用IPv6,可以尝试将`listen_interface`和`rpc_interface`配置为IPv4,如127.0.0.1。

3. **错误消息**:
   提供的错误是在连接尝试被拒绝时产生的。确保所有节点配置正确,且Cassandra允许连接。

4. **Python驱动版本**:
   请确保使用的`cassandra-driver`版本是最新的,兼容你使用的Cassandra版本。

如果这些方法依旧不起作用,可以详细检查一下服务器配置及客户端日志以明确问题进一步的细节。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-4 01:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表