如何缩放psycopg2插入并在python中使用单个进程选择?

时间:2017-09-03 16:42:52

标签: python multithreading postgresql scalability psycopg2

我的插件需要平均大约0.300095081329才能完成对postgres的提交。

这是我的表格式

id_table
    latest_update_id (primary index)
    product_id       (index)
    publish_date

product_meta_table
    latest_update_id    (index)
    product_id          (index)
    meta_related_info1
    meta_related_info2
    ...etc

product_table
    latest_update_id    (index)
    product_id          (index)
    note_related_info1
    note_related_info2
    ....etc

以下是我的一些插页

db_cursor.execute("INSERT INTO id_table (product_id, publish_date)  \
             VALUES (%s, %s) RETURNING latest_update_id",
    (my_dict["product_id"], my_dict["publish_date"])
)

 db_cursor.execute("INSERT INTO product_table ( \
                   latest_update_id, \
                   product_id, \
                   note_related_info1, \
                   note_related_info2, \
                   ...etc)  \
             VALUES (%s, %s, %s, %s) RETURNING *",
    (my_dict["latest_update_id"], 
     my_dict["product_id"],
     my_dict["note_related_info1"],
     my_dict["note_related_info2"])
)       

使用插入时间,我的吞吐量约为1/0.3 = 3qps

我知道我可以通过添加更多实例来横向扩展,但我想尝试看看我是否能够至少达到3000qps

我正在考虑使用异步或线程,但不确定GIL是否会干扰。

关于如何使用psycopg2扩展insert语句,是否有一般的良好实践和技巧?

由于

注意:我使用的是python 2.7

注意:python进程通过https

与sql server通信

注意:每个表的插入是交错的,table2插入table1之后,table3插入table2之后。从技术上讲,table2和table3只需要等待table1完成插入,因为它们需要latest_update_id

2 个答案:

答案 0 :(得分:2)

执行单个插入查询而不是3.注意三重引号和字典参数传递:

H****
H***
How**?
How**? My friend lives in Pomp*** and every time I see her I say "H***" to her, she is very h****

答案 1 :(得分:1)

跟进我的网络评论。

假设你有100ms往返(就像SELECT 1的时间一样)。

如果你想链接查询,那么你将别无选择,只需要用大量值来INSERT ...来分摊往返时间。

这很麻烦,因为您必须对返回的ID进行排序,以插入从属行。此外,如果您的带宽很低,您将会使其饱和,而且无论如何它也不会那么快。

如果您的带宽足够高但ping速度很慢,您可能会想要多线程......但这会产生另一个问题......

而不是说1-2服务器进程非常快速地通过查询进行搅拌,除了浪费宝贵的服务器RAM而等待查询通过慢速网络时,你将有50个进程无所事事。

此外,可能会出现并发和锁定问题。你不会只做INSERT ...你会做一些SELECT FOR UPDATE来获取锁...

...然后其他进程在你的下一个查询通过网络爬行时堆积起来获取该锁...

这就像在并发写入密集型场景中使用MyISAM一样。锁定应该在最短的时间内保持...快速ping有助于将整个查询链从锁定获取放到存储过程中的释放锁定甚至更好,因此它只能保持很短的时间。

因此,请考虑在数据库服务器或同一LAN上的服务器上执行python脚本。