imcs初探

时间:2022-06-18 13:23:13

imcs简介

  https://github.com/knizhnik/imcs

  翻译过来是在内存上的列存储,在对于一张‘静态’的表计算方面很有优势,在许多聚合运算中都有使用线程并行计算,而且其中使用了迭代器来对数据进行tile分割,数据存储在pg的共享内存中,在启动多个session都能够对这块内存进行操作,提高了查询效率。

imcs安装

第一步:修改Makefile或者将imcs目录拷贝到/postgres/contrib/目录下

vim Makefile

 #ifdef USE_PGXS
PG_CONFIG = /usr/local/postgres/bin/pg_config //pg的安装目录
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
#else
#subdir = contrib/imcs
#top_builddir = ../..
#include $(top_builddir)/src/Makefile.global
#include $(top_srcdir)/contrib/contrib-global.mk
#endif [root@centos01 imcs]# make && make install

第二步:创建imcs扩展

 postgres=# create extension imcs ;

 postgres=# \dx
List of installed extensions
Name | Version | Schema | Description
---------+---------+------------+------------------------------
imcs | 1.1 | public | In-Memory Columnar Store postgres=# CREATE TABLE customer
postgres-# (
postgres(# customer_id TEXT,
postgres(# review_date DATE,
postgres(# review_rating INTEGER,
postgres(# review_votes INTEGER,
postgres(# review_helpful_votes INTEGER,
postgres(# product_id CHAR(),
postgres(# product_title TEXT,
postgres(# product_sales_rank BIGINT,
postgres(# product_group TEXT,
postgres(# product_category TEXT,
postgres(# product_subcategory TEXT
postgres(# );

第三步:生成user define funtion来对表进行查询

postgres=# select cs_create('customer','review_date','product_id');

postgres=# select customer_load();

注意1:操作此步会有许多错误,如果没有在postgres.conf中配置,由于没有初始化imcs的hash_table的前提下,往共享内存上插入是段错误的,但是此处没有打印出报错信息。

配置项:shared_preload_libraries = 'imcs'

注意2:postgres=# select customer_load();
ERROR:  NULL values are not supported by columnar store
CONTEXT:  PL/pgSQL function customer_load(boolean,text) line 1 at RETURN

在load数据时是不支持NULL value,但是imcs提供了可配置的选项让0来替代null数据,但是这种替代是毫无意义的,很多计算都是不准确的。

配置项:imcs.substitute_nulls=1

注意3:由于imcs使用字典来存储字符串,因此在开辟hash的时候需要将字典指定大一些,才能够装下这些字典。

配置项:imcs.dictionary_size=100000

注意4:还有一个配置选项是关于多线程的,如果配置>=2,则都会启动多线程来对存储上的数据分割计算,最后merge产生结果

配置项:imcs.n_threads=4

postgres=# select customer_load();
 customer_load
---------------
        176773
此时已经将pg的一张表的数据全部load到共享内存上了,可以使用imcs提供的udf函数对共享内存进行查询了。

查询对比如下:

postgres=# select cs_sum(review_rating) from customer_get();
cs_sum
-------- ( row) Time: 16.420 ms
postgres=# select sum(review_rating) from customer ;
sum
-------- ( row) Time: 133.685 ms

对于大部分聚合运算通过imcs提供的udf函数查询都能够比正常sql对pg原生表查询速度快。

还需要注意

postgres=# insert into customer select * from customer limit ;
INSERT
Time: 12.974 ms
postgres=# select cs_sum(review_rating) from customer_get();
cs_sum
-------- postgres=# select sum(review_rating) from customer ;
sum
--------

由此可以得到结论:在insert、update、delete数据后需要重新load数据到共享内存。

优点:1、多线程并行计算

   2、运算效率高

   3、迭代器是个多叉树结构,能够对tile数据mapreduce。

缺点:1、在做增删改操作后需要重新load一遍数据,如果数据量大,就消耗的时间

   2、不支持null数据

   3、代码使用宏编写,不易看懂,很难进行二次开发