【问题标题】:Is there any way to differentiate sessions of each client in cassandra QueryHandler?有什么方法可以区分 cassandra QueryHandler 中每个客户端的会话吗?
【发布时间】:2018-05-08 14:57:57
【问题描述】:

我的目标是通过编写自定义 QueryHandler 实现来记录每个会话的唯一查询,因为在我们的案例中记录所有查询会导致性能下降。

考虑这种情况:如果用户使用 java 客户端连接到 cassandra 集群并执行“select * from users where id = ?” 100 次。 另一个用户从 cqlsh 连接并执行了 50 次相同的查询。所以在这种情况下我只想记录两个查询。为此,我每次登录都需要一个唯一的会话 ID。

Cassandra 提供了以下接口,所有请求都会在该接口中启动,但它的任何 api 都没有提供任何 sessionId 来区分上述情况中描述的两个不同会话。

org.apache.cassandra.cql3.QueryHandler

注意:我能够获取远程地址/端口,但我想要一些在用户登录时创建并在他断开连接时被销毁的 id。

【问题讨论】:

    标签: cassandra cassandra-2.1


    【解决方案1】:

    queryState.getClientState().getRemoteAddress() 中,地址+端口在会话池中的每个 tcp 连接都是唯一的。但是,每个连接上可以有多个并发请求,并且一个会话每个主机可以有多个连接。也不能保证在客户端从一个请求到另一个请求将使用相同的 tcp 连接。

    但是,单个会话不能作为 2 个不同的用户连接(连接初始化的一部分),因此您描述的场景从同一 Session 对象的角度来看是不可能的。我认为考虑到协议/驱动程序的工作方式,仅使用地址作为唯一性的关键就可以了。它至少会删除一些内容。

    您实际上是在处理内联日志记录还是将其推迟到异步状态?如果使用 logback,它应该使用异步 appender,但如果您将事件同步发布到另一台服务器,最好将所有事件放在一个队列中并让它在另一个线程中进行重复数据删除,这样您就不会损害延迟。

    【讨论】:

    • 嗨,克里斯,感谢您的回复。我相信 getRemoteAddress() 不会区分,以防万一有不同的客户端从同一台机器连接到 cassandra,因为主机和端口对所有人都是相同的。目前我没有使用异步附加程序,但我也会尝试。 asynch appender 在内存和 cpu 利用率方面也有一些缺点,所以我需要在配置它时牢记这些要点。最初我打算只使用同步附加器来测试性能。
    • 端口不一样,目标端口是 9042,但是每个 tcp 连接都有一个唯一的源端口,因此内核可以区分哪个连接到哪个连接。然而,一个 Session 确实代表一个连接池,因此它可以跨越多个,但这只是一个开始。我会推荐异步,内存问题可以通过使其成为可丢弃队列来解决(例如,这是 C* 为跟踪执行程序所做的)。
    • 感谢 Chris 提供宝贵的 cmets。我会记住你的建议。
    • 嗨,克里斯,你知道有什么方法可以区分 org.apache.cassandra.cql3.QueryHandler 中的主节点和副本吗?现在,如果集群的复制因子为 3,那么一个插入请求会发送到所有 3 个节点的 QueryHandler。我看到了一个 api ClientState.isInternal 但这并不相同,它用于内部系统键空间操作。
    猜你喜欢
    • 2018-09-06
    • 1970-01-01
    • 1970-01-01
    • 2019-04-17
    • 1970-01-01
    • 2012-08-12
    • 2011-08-21
    • 2016-04-26
    • 1970-01-01
    相关资源
    最近更新 更多