imcs初探

imcs简介

  https://github.com/knizhnik/imcs

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

imcs安装

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

vim Makefile

 1 #ifdef USE_PGXS
 2 PG_CONFIG = /usr/local/postgres/bin/pg_config  //pg的安装目录
 3 PGXS := $(shell $(PG_CONFIG) --pgxs)
 4 include $(PGXS)
 5 #else
 6 #subdir = contrib/imcs
 7 #top_builddir = ../..
 8 #include $(top_builddir)/src/Makefile.global
 9 #include $(top_srcdir)/contrib/contrib-global.mk
10 #endif
11 
12 [root@centos01 imcs]# make && make install

 

第二步:创建imcs扩展

 1 postgres=# create extension imcs ;
 2 
 3 postgres=# \dx
 4                  List of installed extensions
 5   Name   | Version |   Schema   |         Description          
 6 ---------+---------+------------+------------------------------
 7  imcs    | 1.1     | public     | In-Memory Columnar Store
 8 
 9 postgres=# CREATE  TABLE customer
10 postgres-# (
11 postgres(#     customer_id TEXT,
12 postgres(#     review_date DATE,
13 postgres(#     review_rating INTEGER,
14 postgres(#     review_votes INTEGER,
15 postgres(#     review_helpful_votes INTEGER,
16 postgres(#     product_id CHAR(10),
17 postgres(#     product_title TEXT,
18 postgres(#     product_sales_rank BIGINT,
19 postgres(#     product_group TEXT,
20 postgres(#     product_category TEXT,
21 postgres(#     product_subcategory TEXT
22 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 
--------
 536823
(1 row)

Time: 16.420 ms
postgres=# select sum(review_rating) from customer ;
  sum   
--------
 536823
(1 row)

Time: 133.685 ms

 

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

还需要注意

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

 

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

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

   2、运算效率高

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

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

   2、不支持null数据

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

posted @ 2016-11-22 17:15  hi龙卷风  阅读(619)  评论(0编辑  收藏  举报