cassandra基本概念(连接池)和使用实践(python)

cassandra基本概念(连接池)和使用实践(python)

基本概念

Builder ≠ Cluster ≠ Session ≠ Connection ≠ Statement

Cluster.Builder:用于配置和创建集群

Cluster:操作集群,控制连接节点和一些属性,项目中只需要定义一个

Cluster 四种Retry重试策略(对数据库的操作失败后的重试)

  • DefaultRetryPolicy没有查询到数据,或者写入时超时的情况下进行重新查询

  • DowngradingConsistencyRetryPolicy:与DefaultRetryPolicy一样,不同点是考虑了最终数据一致性问题

  • FallthroughRetryPolicy:这一策略不重试查询,但允许客户端业务逻辑实现重试

  • LoggingRetryPolicy:不重试查询,用来记录日志信息,info级别

Cluster 两种节点重连策略(节点连接不上重新连接)

  • ConstantReconnectionPolicy:固定时间间隔进行重连

  • ExponentialReconnectionPolicy:指数级别增加重连时间,但不会超过最大重连时间

Session:会话,执行CQL语句,项目中只需要定义一个

本身不是一个连接,但它管理连接。

会话会管理一个连接池,并且连接池和每一个节点通常至少会维持一个连接。

这就是为什么您应尽可能重用Session对象的原因。应用程序不应该直接管理或访问连接。

在执行语句时Session会选择要查询的节点,故当多个客户端同时使用同一会话时,它们实际上可能使用不同的物理连接。

注意: 在web项目中session对象应该创建为全局对象供DAO或者Model层使用,而不是每次请求接入都创建,请求处理完后又关闭

关于连接池官方说法
You just need to create one Session object per your application, and then driver will do all necessary pooling for you. Cassandra protocol allows to execute multiple queries over the one connection, and everything just work out of box - you can execute queries from multiple threads using the same Session object. If necessary (but you need to have a good reason for it), you can increase number of connections from driver to every host in cluster, but in the big cluster this may lead to increased resource consumption

Statement:会话内执行语句

定义CQL,可以指定查询属性,如fetchSize,语句可以准备也可以不准备。

SimpleStatement

一个简单的,没有准备的语句。

Prepared Statements

针对至少一个Cassandra节点准备的预备语句,并且驱动程序会在必要时针对新节点和重新启动的节点进行重新准备。

预备语句是由Cassandra解析并保存以供以后使用的查询。当驱动程序使用一条准备好的语句时,它只需要发送参数值来进行绑定。这降低了Cassandra中的网络流量和CPU利用率,因为Cassandra不必每次都重新解析查询。

请注意,PreparedStatement准备语句的占位符是?字符,这与简单的未准备好的SimpleStatement语句不同,此类的实例不应直接创建,而应通过Session.prepare()创建。

注意: PreparedStatement应该只准备一次。重新准备一条语句可能会影响性能(因为该操作需要网络往返)。

ResultSet:每次同步执行CQL都会返回这个类

ResultSetFuture:每次异步执行CQL都会返回这个类

Row类:查询的结果中的一行数据

QueryBuilder类:可以动态构造CQL中的Select、Insert、Update、Delete

python使用实践

安装

pip install cassandra-driver

实践

import uuid
from cassandra.cluster import Cluster
from cassandra.query import BatchStatement, BatchType

CASSANDRA_NODES = ['xxx.xxx.xxx.xxx']
CASSANDRA_KEYSPACE = 'test'

cluster = Cluster(CASSANDRA_NODES)

# 项目中 session 应该在系统启动后初始化为全局变量
session = cluster.connect(CASSANDRA_KEYSPACE, wait_for_all_pools=True)

# 建表
session.execute('create table user(user_id uuid primary key, name text, age int, email varchar)')


class User:
    @property
    def _get_prepare_statement(self):
        return session.prepare("""SELECT * FROM user WHERE user_id=? limit 1""")

    @property
    def _insert_prepare_statement(self):
        return session.prepare("""INSERT INTO user (user_id, name, age, email) VALUES (?, ?, ?, ?)""")

    def get_user(self, user_id):
        user = session.execute(self._get_prepare_statement, [user_id]).one()
        return user

    def create_user(self, user_id, name, age, email):
        session.execute(self._insert_prepare_statement, [user_id, name, age, email])

    def bulk_create_user(self, users: list):
        batch = BatchStatement(batch_type=BatchType.UNLOGGED)

        for user in users:
            batch.add(self._insert_prepare_statement, (user['user_id'], user['name'], user['age'], user['email']))

        session.execute(batch)

# 应使用单例模式创建,或者使用类方法和属性的方式定义
user_manager = User()

user_id = uuid.uuid4()
user_manager.create_user(user_id, 'dd', 18, '[email protected]')


user = user_manager.get_user(user_id)
print(user)


users = [{'user_id': uuid.uuid4(), 'name': 'xiaoming', 'age': 22, 'email': '[email protected]'},
         {'user_id': uuid.uuid4(), 'name': 'zhangsan', 'age': 21, 'email': '[email protected]'}]

user_manager.bulk_create_user(users)


猜你喜欢

转载自blog.csdn.net/pushiqiang/article/details/109112159
今日推荐