代码之家  ›  专栏  ›  技术社区  ›  Pierre

如何连接到塔架应用程序内的卡桑德拉?

  •  10
  • Pierre  · 技术社区  · 14 年前

    我创建了一个新的Pylons项目,并希望使用Cassandra作为我的数据库服务器。我计划使用皮卡萨能够使用卡桑德拉0.7贝塔。

    • 启动应用程序时创建池
    • 如果已使用连接,请在处理请求后释放它

    另外,有什么重要的事情我应该知道吗?当我看到一些评论,如“在使用use\u threadlocal=True的QueuePool时要小心,特别是在启用重试的情况下。可能需要同步来防止连接在另一个线程使用时发生更改。”,这到底是什么意思?

    -- 皮埃尔

    2 回复  |  直到 14 年前
        1
  •  2
  •   Pierre    14 年前

    好。我多工作了一点。实际上,使用连接管理器可能不是一个好主意 应该 作为模板上下文。另外,为每个线程打开一个连接并不是什么大事。每个请求打开一个连接将是。

    最后我只有 pycassa.connect_thread_local()

        2
  •  1
  •   Pierre    14 年前

    可以。 我工作了一点,学到了很多,我找到了一个可能的答案。

    创建池

    创建游泳池的最佳位置似乎在应用程序中_全局.py文件,它基本上是对象的容器,这些对象在“应用程序的整个生命周期”中都是可访问的。事实上,这正是我想要的游泳池。

    我刚刚在文件末尾添加了我的init代码,它从pylons配置文件中获取设置:

    """Creating an instance of the Pycassa Pool"""
    kwargs = {}
    
    # Parsing servers
    if 'cassandra.servers' in config['app_conf']:
        servers = config['app_conf']['cassandra.servers'].split(',')
        if len(servers):
            kwargs['server_list'] = servers
    
    # Parsing timeout
    if 'cassandra.timeout' in config['app_conf']:
        try:
            kwargs['timeout'] = float(config['app_conf']['cassandra.timeout'])
        except:
            pass
    
    # Finally creating the pool
    self.cass_pool = pycassa.QueuePool(keyspace='Keyspace1', **kwargs)
    

    我本可以做得更好,比如在函数中移动它,或者支持更多的参数(池大小,…)。我会的。

    好。似乎有一个简单的方法:在文件中 base.py ,添加如下内容 c.conn = g.cass_pool.get() WSGIController ,大概是 c.conn.return_to_pool() 之后。这很简单,而且有效。但即使控制器不需要连接,它也会从池中获得连接。我得再深入一点。

    创建连接管理器

    我有一个简单的想法,就是创建一个类,该类将在 文件,它将在请求时自动从池中获取连接(并在请求后释放连接)。这是一个非常简单的类:

    class LocalManager:
        '''Requests a connection from a Pycassa Pool when needed, and releases it at the end of the object's life'''
    
        def __init__(self, pool):
            '''Class constructor'''
            assert isinstance(pool, Pool)
            self._pool = pool
            self._conn = None
    
        def get(self):
            '''Grabs a connection from the pool if not already done, and returns it'''
            if self._conn is None:
                self._conn = self._pool.get()
            return self._conn
    
        def __getattr__(self, key):
            '''It's cooler to write "c.conn" than "c.get()" in the code, isn't it?'''
            if key == 'conn':
                return self.get()
            else:
                return self.__dict__[key]
    
        def __del__(self):
            '''Releases the connection, if needed'''
            if not self._conn is None:
                self._conn.return_to_pool()
    

    c.cass = CassandraLocalManager(g.cass_pool) 在调用WSGIController之前 基本.py , del(c.cass) 之后,我就完了。

    conn = c.cass.conn
    cf = pycassa.ColumnFamily(conn, 'TestCF')
    print cf.get('foo')
    

    我不知道这是不是最好的办法。如果没有,请告诉我=) 另外,我仍然不理解Pycassa源代码中的“同步”部分。如果我的情况需要,我应该怎么做来避免问题。