多节点Cassandra集群与客户端读取请求不一致

2 投票
1 回答
1205 浏览
提问于 2025-04-18 00:35

我有一个运行中的Cassandra集群,里面有两个节点,我通过python-driver API执行一些构建好的CQL查询。我正在对我创建的一系列模型进行单元测试,这些模型主要是为了简化Cassandra API,以便其他开发者使用。当我在单节点集群上测试时,所有的测试都通过了,但在添加了第二个节点后,测试结果就变得非常不稳定,要么失败,要么出错,要么偶尔通过,完全没有规律可言。

我通过比较插入到Cassandra中的对象和从Cassandra查询得到的对象来检查结果,使用的是 self.__dict__ == other.__dict__,因为我根据从Cassandra收到的列值来填充类的字段。

我认为我找到了问题所在。在我的种子节点上:

cqlsh:mykeyspace> select id,created_at from users;

id | created_at
----+--------------
10 | 139621386780
11 | 139621386780
 8 | 139621386780
 7 | 139621386780
 6 | 139621386780
 9 | 139621386780
12 | 139621386780

(7 rows)

在我的第二个节点上:

cqlsh:mykeyspace> select id,created_at from users;

 id | created_at
----+--------------
  8 | 139621370181
  7 | 139621370181
  9 | 139621370181

(3 rows)

这里的第一列是一个整数ID,第二列是一个Python的 datetime 对象。我认为发生的情况是,当我向 users 插入一行数据时,这行数据会被插入到第一个或第二个节点上,但当我尝试从Cassandra中检索这个对象时,我可能是从一个不同的节点读取数据,而不是刚刚插入数据的那个节点,因为Cassandra是允许这样做的。然而,如果我设置了 consistency_level=ALL(我的python CQL调用中确实是这样设置的),难道我不应该收到最新的行数据,而不是之前插入的某一行吗?


更新

请注意,唯一标识符被故意去掉了。

在种子节点上:

$ nodetool status
Datacenter: 243
===============
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address         Load       Tokens  Owns   Host ID                               Rack
UN  IP Address 0  136.47 KB  256     100.0%  ownsuuid  58

$ nodetool gossipinfo
/IP Address 0
  HOST_ID:ownsuuid
  SCHEMA:schema
  RPC_ADDRESS:0.0.0.0
  RELEASE_VERSION:2.0.4
  STATUS:NORMAL,-1102599059356328037
  SEVERITY:0.0
  RACK:58
  LOAD:150498.0
  DC:243
  NET_VERSION:7
/IP Address 1
  SCHEMA:schema
  HOST_ID:ownsuuid
  RPC_ADDRESS:0.0.0.0
  RELEASE_VERSION:2.0.4
  STATUS:NORMAL,-1102599059356328037
  SEVERITY:0.0
  RACK:181
  LOAD:148937.0
  DC:241
  NET_VERSION:7

在另一个非种子节点上:

~$ nodetool status
Datacenter: 241
===============
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address          Load       Tokens  Owns   Host ID                               Rack
UN  IP Address 1  145.45 KB  256     100.0%  ownsuuid  181

$ nodetool gossipinfo
/IP Address 0
  STATUS:NORMAL,-1102599059356328037
  LOAD:139743.0
  RELEASE_VERSION:2.0.4
  RACK:58
  SCHEMA:schema
  SEVERITY:0.0
  NET_VERSION:7
  HOST_ID:ownsuuid
  RPC_ADDRESS:0.0.0.0
  DC:243
/IP Address 1
  STATUS:NORMAL,-1102599059356328037
  LOAD:164405.0
  RELEASE_VERSION:2.0.4
  RACK:181
  NET_VERSION:7
  SCHEMA:schema
  SEVERITY:0.0
  HOST_ID:ownsuuid
  RPC_ADDRESS:0.0.0.0
  DC:241

1 个回答

1

听起来你遇到的问题更像是节点之间的沟通问题,而不是其他什么。你知道“nodetool”这个诊断工具吗?它在你Cassandra的bin目录里可以找到。

我在亚马逊的EC2服务器上运行着一个有两个节点的Cassandra集群,我可以在bin目录下运行以下命令:

bash nodetool status

bash nodetool gossipinfo

当你运行这些命令时,应该能看到你所有的节点。这至少能确认你的节点之间能够正常沟通,并且数据能够正确分配。对于我的集群,一旦确认所有节点都能沟通,我可以在任意一个节点上用cqlsh运行查询,并得到100%一致的结果。

另外,你有没有在“conf”文件夹里的cassandra.yaml文件中配置节点的种子值?一旦你的第一个节点启动并运行,第二个节点应该使用第一个节点的IP地址或名称作为它的种子。

撰写回答