我创建了一个新的Pylons项目,并希望使用Cassandra作为我的数据库服务器。我打算使用Pycassa来使用cassandra 0.7beta。 不幸的是,我不知道在哪里实例化连接以使其在我的应用程序中可用。
目标是:
此外,我应该知道一些重要事项吗?当我看到一些评论时,“使用带有use_threadlocal = True的QueuePool时要小心,特别是启用了重试。可能需要同步以防止连接在另一个线程正在使用时发生变化。”,这究竟是什么意思?
感谢。
- 皮尔
答案 0 :(得分:2)
好。我工作了一点。实际上,使用连接管理器可能不是一个好主意,因为应该是模板上下文。此外,为每个线程打开一个连接并不是什么大问题。每个请求打开一个连接将是。
我最终在app_globals中只有pycassa.connect_thread_local()
,我就去了。
答案 1 :(得分:1)
好。 我工作了一点,我学到了很多,我找到了一个可能的答案。
创建池的最佳位置似乎位于app_globals.py文件中,该文件基本上是对象的容器,可以在“应用程序的整个生命周期”中访问。事实上,正是我想要一个游泳池。
我刚刚在文件的末尾添加了我的初始化代码,它从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()
之类的内容。这很简单,也很有效。但即使控制器不需要,也可以从池中获得连接。我必须深入挖掘一下。
我有一个简单的想法,即创建一个类,该类将在base.py
文件中的每个请求中实例化,并且在请求时自动从池中获取连接(并在之后释放)。这是一个非常简单的课程:
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)
,base.py
之后调用WSGIController之前添加了del(c.cass)
,我已经完成了。
它有效:
conn = c.cass.conn
cf = pycassa.ColumnFamily(conn, 'TestCF')
print cf.get('foo')
\ O /
我不知道这是否是最好的方法。如果没有,请让我知道=) 另外,我仍然不理解Pycassa源代码中的“同步”部分。如果在我的情况下需要它,我该怎么做才能避免问题。
感谢。