如何使用单个Cassandra Client对象连接多个keyspace?
如何用Cassandra Driver连接多个Keyspace?
原单Keyspace连接代码
/config/db.ts
import cassandra from "cassandra-driver"; class Cpool { static _pool: cassandra.Client; static connect(options: any) { this._pool = new cassandra.Client(options); } static execute(query: string, params?: cassandra.ArrayOrObject | undefined, options?: cassandra.QueryOptions | undefined) { return this._pool.execute(query, params, options); } } export { Cpool };
index.ts
const default_options = { contactPoints: [process.env.CONTACT_POINTS], localDataCenter: process.env.LOCAL_DATA_CENTER, keyspace: process.env.KEYSPACE, }; try { await Cpool.connect(default_options); console.log("Connected to Cassandra"); } catch (err) { console.log(err); }
多Keyspace连接方案
不需要为每个Keyspace创建单独的客户端实例,单个cassandra.Client即可访问集群内的所有Keyspace,推荐两种实现方式:
方案1:查询语句显式指定Keyspace
这是最安全且无并发冲突的方案,直接在SQL语句前加上Keyspace前缀:
// 操作keyspace1的表 await Cpool.execute("SELECT * FROM keyspace1.users WHERE id = ?", [userId]); // 操作keyspace2的表 await Cpool.execute("INSERT INTO keyspace2.products (id, name) VALUES (?, ?)", [productId, productName]);
如果觉得写前缀麻烦,可以给Cpool扩展一个带Keyspace参数的方法:
// 修改/config/db.ts,添加带keyspace的execute方法 static executeWithKeyspace(keyspace: string, query: string, params?: cassandra.ArrayOrObject | undefined, options?: cassandra.QueryOptions | undefined) { const fullQuery = `${keyspace}.${query}`; return this._pool.execute(fullQuery, params, options); } // 使用示例 await Cpool.executeWithKeyspace("keyspace1", "SELECT * FROM users WHERE id = ?", [userId]);
方案2:切换客户端的默认Keyspace
如果大部分操作集中在某个Keyspace,偶尔需要切换,可以通过执行USE语句切换客户端的默认Keyspace:
// 修改/config/db.ts,添加切换方法 static async switchKeyspace(keyspace: string) { await this._pool.execute(`USE ${keyspace}`); } // 使用示例 // 初始连接可以不指定keyspace,或者指定一个默认值 const default_options = { contactPoints: [process.env.CONTACT_POINTS], localDataCenter: process.env.LOCAL_DATA_CENTER, // 去掉keyspace配置,或者保留一个默认的 }; await Cpool.connect(default_options); // 切换到keyspace1并操作 await Cpool.switchKeyspace("keyspace1"); await Cpool.execute("SELECT * FROM users WHERE id = ?", [userId]); // 切换到keyspace2并操作 await Cpool.switchKeyspace("keyspace2"); await Cpool.execute("INSERT INTO products (id, name) VALUES (?, ?)", [productId, productName]);
⚠️ 注意:这种方式在并发场景下会有冲突,因为客户端实例是共享的,切换Keyspace会影响所有后续执行的查询。如果是多请求并发的服务,优先用方案1。
内容的提问来源于stack exchange,提问作者best_of_man
相关产品推荐
相关产品推荐

