Redis数据导入工具优化过程总结

Redis数据导入工具优化过程总结

背景

使用C++开发了一个Redis数据导入工具
从oracle中将所有表数据导入到redis中;
不是单纯的数据导入,每条oracle中的原有记录,需要经过业务逻辑处理,
并添加索引(redis集合);
工具完成后,性能是个瓶颈;

优化效果

使用了2个样本数据测试:
样本数据a表8763 条记录;
b表940279 条记录;

优化前,a表耗时11.417s;
优化后,a表耗时1.883s;

用到的工具

gprof, pstrace,time

使用time工具查看每次执行的耗时,分别包含用户时间和系统时间;
使用pstrace打印实时运行,查询进程主要的系统调用,发现耗时点;
使用gprof统计程序的耗时汇总,集中精力优化最耗时的地方;
使用简介:
1.对g++的所有编辑和连接选项都必须要加上-pg(第一天由于没有在连接处加上-pg选项,导致无法出统计报告);
2.执行完程序后,本目录会产生gmon.out文件;
3.gprof redistool gmou.out > report,生成可读文件report,打开report集中优化最耗时的函数;

优化过程

优化前11.417s:

time ./redistool im a a.csv
real    0m11.417s
user    0m6.035s
sys     0m4.782s (发现系统调用时间过长)

文件内存映射

系统调用时间过长,主要是文件读写,初步考虑是读取文件时,调用api次数过于频繁;
读取样本采用的是文件fgets一行行的读取,采用文件内存映射mmap后,可直接使用指针操作整个文件内存快;

日志开关提前

改进了文件读写后,发现优化效果比较有限(提高了2s左右);fgets是C的文件读取库函数,相比系统read(),是带了缓冲区了,应该不会太慢(网上有人测试,文件内存映射相比fgets()能快上一个数量级,感觉场景应该比较特殊);

之后通过pstrace工具发现log.dat打开次数过多;原来是调试日志的开关写到了后面,导致 调试日志都是会打开日志文件open("log.dat");

将日志开关提前;改进后,3.53s

time ./redistool im a a.csv
real    0m3.530s
user    0m2.890s
sys     0m0.212s

vector空间预先分配

后续通过gprof分析,某个函数的vector内存分配次数多,并有不少复制次数:
改进以下这行代码:

vector <string> vSegment;

使用静态vector变量,并预先分配内存:

static vector <string> vSegment;
vSegment.clear();
static int nCount = 0;
if( 0 == nCount)
{
    vSegment.reserve(64);
}
++nCount;

优化后,提升至2.286s

real    0m2.286s
user    0m1.601s
sys     0m0.222s

同样,另外一个类中的成员vector也使用预先分配空间(在构造函数中):

m_vtPipecmd.reserve(256);

优化后,提升至2.166s;

real    0m2.166s
user    0m1.396s
sys     0m0.204s

函数改写 && 内联

继续执行程序,发现SqToolStrSplitByCh()函数消耗过大,改写整个函数逻辑,并将改写后的函数内联:
优化后,提升至1.937s

real    0m1.937s
user    0m1.301s
sys     0m0.186s

去除调试符和优化监测符号

最后,去掉debug和pg调试符号后,最终效果为1.883s;

real    0m1.883s
user    0m1.239s
sys     0m0.191s

满足生产要求

以上最后几步看似毫秒级的提升,扩大到全表数据后,效果就很明显了;
优化后,生产上a表为152w,导入耗时大约326s(~6分钟);

b表数据420w,导入耗时大约1103s(~18分钟)

Posted by: 大CC | 28JUN,2015

博客:blog.me115.com [订阅]

Github:大CC

时间: 2024-09-30 10:57:42

Redis数据导入工具优化过程总结的相关文章

ImportTsv-HBase数据导入工具

一.概述 HBase官方提供了基于Mapreduce的批量数据导入工具:Bulk load和ImportTsv.关于Bulk load大家可以看下我另一篇博文. 通常HBase用户会使用HBase API导数,但是如果一次性导入大批量数据,可能占用大量Regionserver资源,影响存储在该Regionserver上其他表的查询,本文将会从源码上解析ImportTsv数据导入工具,探究如何高效导入数据到HBase. 二.ImportTsv介绍 ImportTsv是Hbase提供的一个命令行工具

redis数据导入导出

在2017年,项目上的redis集群需要从2.8版本更换为3.2版本,此时涉及到redis数据key的迁移,经百度.×××,发现有三种方法可以实现1.第三方工具redis-dump.redis-load实现2.通过aof机制导入导出,需要开启aof功能3.通过rdb存储机制迁移数据,此方法最为简单,直接dump $key.restore $key即可 此篇主要介绍第一种方式,redis-dump.redis-load实现redis的数据导入导出,直接进入主题 redis-dump,要求ruby版

oracle批量数据导入工具 sqlldr

sqlldr工具参数: [[email protected] ~]$ sqlldr SQL*Loader: Release 11.2.0.3.0 - Production on Wed Nov 19 09:47:56 2014 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. Usage: SQLLDR keyword=value [,keyword=value,...] Valid Keyw

《java提高数据导入效率优化思路》

写在前边的实现需求: 1.总共10万个电话号码: 2.电话号码中有重复和错误: 3.查找出正确的号码(不重复): 一.优化前的实现方式: 1.先用正则过滤一遍10万条数据,找出错误的: 2.用List.Contains验证重复数据,List.Add添加不重复数据: 3.最终从List中取出正确的数据. 1 public class appMain { 2 final static int _capacity = 1000000; 3 final static Random rand = new

Redis 数据导入导出,redis-dump命令

安装redis-dump 工具 yum install ruby rubygems ruby-devel gem install redis-dump -V 使用方法 没有密码: # 导出 redis-dump -u 127.0.0.1:6379 -d 1 > test.json # 导入 < test.json redis-load -u 10.137.195.25 有密码: # 导出 redis-dump -u :123456@127.0.0.1:6379 -O > test.jso

redis数据导入与导出以及配置使用

最近在研究redis 遇到redis requires Ruby version >= 2.2.2问题 解决办法是 先安装rvm,再把ruby版本提升至2.3.3 1.安装curl sudo yum install curl 2. 安装RVM curl -L get.rvm.io | bash -s stable 3. source /usr/local/rvm/scripts/rvm 4. 查看rvm库中已知的ruby版本 rvm list known 5. 安装一个ruby版本 rvm in

KDD数据导入sqlserver2005数据库

请先读一下这篇文章的内容:http://wenku.baidu.com/link?url=hFpkoQMUT-I4YxR6bLQeia45H-Qv4jz3VTrxpog_zXOohoOSLfdnxc7Jagj1k04KeReerCLAaZ8n8-YMXQPmsG5MJPS6aUNSY-Fr8EcqhKC 在这篇文章中,作者已经写的很好,但本人在将数据导入sqlserver的过程中,没有写那么复杂的程序.但实现了导入数据这个功能.下面,跟大家一一说来. 我用的开发平台是MyEclipse,但从网上

使用redis-dump-load工具导入导出redis数据

需求环境 Redis-dump-load是基于python2.7,利用redis模块编写的一个导出/导入redis数据的一个python程序,因此,需求环境如下: python 2.7 pip2.7 python.redis模块 安装程序 # pip-2.7 install redis # cd /usr/local # git clone https://github.com/p/redis-dump-load.git # cd redis-dump-load # ./redisdl.py -

Oracle exp/imp数据导入导出工具基本用法

一.获取帮助 exp/imp help=y 二.数据导出 1.将数据库完全导出,设置full选项exp system/[email protected] file=d:\db.dmp full=y 2.导出数据库结构,不导出数据,设置rows选项exp system/[email protected] file=d:\db.dmp rows=n full=y 3.当导出数据量较大时,可以分成多个文件导出,设置filesize选项exp system/[email protected] file=