首页 新闻 会员 周边

hiredis存入的问题

0
悬赏园豆:50 [待解决问题]

用一个循环一千二百万次的for循环把一个qlist加到足够长,这时候可以正常的序列化后存入到redis中(string和list类型都可以存,其他的没试),但是把循环次数加到一千五百万的时候程序就崩溃了,不知道是什么原因?redis不是内存不限制就可以无限存入吗,为什么什么这个程序会出错呢

问题补充:

源码

#ifndef REDIS

#define REDIS

#include<iostream>

#include<string.h>

#include<hiredis/hiredis.h>

 

#include<qlist.h>

#include<qdatastream.h>

#include <qmap.h>

#include<QFile>

#include <QtDebug>

using namespace std;

class redis

{

public:

 

    void connect(char* ip,int port)      //连接redis的函数

    {

        this->c = redisConnect(ip, port); //redisConnect 参数值是redis的IP和接口

        if(c != NULL && c->err)             //返回值c是程序与redis传输的一个接口

        {

            cout<<"Error:"<<c->errstr<<endl;

            redisFree(c);

        }

        cout<<"successful connection."<<endl;

    }

 

 

 

    void del(char *key)            //删除函数

    {

        char l[20] = "DEL ";

        strcat(l,key);

        reply =(redisReply*)redisCommand(c,l);  //del key命令删除key的值

        //freeReplyObject(reply);  //redisCommand函数返回值类型不是redisReply,需要转

    }

 

    void serialist(QList<QString> &list)//将qlist序列化后编码函数

    {

        QByteArray ab2;

        QDataStream outStream(&ab2, QIODevice::WriteOnly);

        outStream << list;

        aa=ab2.toBase64();     //将序列化后的数据编码成为64位ASCII码

 

    }

    void wl(char* key)                      //write list

    {

        char* ab = aa.data();//将编码后的数据转化成char*类型

        char* mid = (char*)malloc((strlen("lpush ")+strlen(key)+strlen(" ")+strlen(ab))*sizeof(char)+1);//动态分配内存空间

        strncat(mid,"lpush ",10);

        strcat(mid,key);

        strcat(mid," ");

        strcat(mid,ab);

        reply = (redisReply*)redisCommand(c,mid);//redis命令lpush key value

        //cout<<reply->type<<endl;

 

        if((reply->type == REDIS_REPLY_ERROR))//如果程序执行错误,返回错误原因

        {

            cout<<reply->str<<endl;

            cout<<reply->len<<endl;

 

        }

        freeReplyObject(reply);

        free(mid);

    }

 

  void rr(char* key)                                     //read list

    {

      char* l = (char*)malloc((strlen("lrange ")+strlen(key)+strlen(" 0 -1"))*sizeof(char)+1);

        strcpy(l,"lrange ");

        strcat(l,key);

        strcat(l," 0 -1");

        reply =(redisReply*)redisCommand(c,l);//redis命令 lrange key 0 -1

        if(reply->type == REDIS_REPLY_ARRAY)

        {

 

            for(long j = 0;j < reply->elements;j++)//遍历需要取出的文件解码后存入readl

             {

                   readl.append( QByteArray::fromBase64(reply->element[j]->str));

             }

        }

     }

 

    void printflist()//反序列化并打印

    {

        QDataStream inStream(&readl, QIODevice::ReadOnly);

        QList<QString> aa2 ;

        inStream>>aa2;

        qDebug()<<aa2;

 

    }

private:

    redisContext* c;

    redisReply* reply;

    QByteArray aa;

    QByteArray readl;

 

 

 

 

 

};

 

 

#endif // REDIS

 

 

#include"redis1.h"

#include<time.h>

int main()

{

   QList<QString> list;

 

   for(int i= 0 ;i<12000000;i++)//构建需要序列化的qlist

    {

        char val[10];

        char ab[100] = "asdfghj";

        sprintf(val,"%d",i);

        strncat(ab,val,100);

        QString str1;

        str1= QString(QLatin1String(ab));

 

        list<<str1;

    }

     redis r;

    r.connect("127.0.0.1",6379);//连接redis

     double duration;

    clock_t start, finish;//构建时间监视器,看程序运行时间

    start = clock();

    r.serialist(list);

    list.clear();//释放qlist内容。

    r.wl("liyayat1");

    //r.del("liyayat1");

    r.rr("liyayat1");

    r.printflist();

    finish = clock();

    duration = (double)(finish - start)/CLOCKS_PER_SEC;

    cout<<duration<<endl;

    return 0;

}

关博兰的主页 关博兰 | 初学一级 | 园豆:152
提问于:2017-05-09 15:14
< >
分享
所有回答(4)
0

内存不限制就可以无限存入

还行吧.你的内存多大?

吴瑞祥 | 园豆:29449 (高人七级) | 2017-05-09 15:26


   QList<QString> list;

   for(int i= 0 ;i<15000000;i++)
    {
        char val[10];
        char ab[100] = "asdfghj";
        sprintf(val,"%d",i);
        strncat(ab,val,100);
        QString str1;
        str1= QString(QLatin1String(ab));
       list<<str1;

 

 

就是这些,我测了一下

应该有一百兆多一点点

支持(0) 反对(0) 关博兰 | 园豆:152 (初学一级) | 2017-05-09 15:29
0

一次性给redis这么大的数据这个不太合适吧,这个很容易timeout的,你直接一个个lpush,再加个pipeline不行么?

Daniel Cai | 园豆:10424 (专家六级) | 2017-05-09 15:38

老师要求最少三千万的循环才行,这样存入出现错误是timeout的问题吗~如果要解决的话是不是应该在配置文件里面修改timeout的时间~修改到多少比较合适啊~

支持(0) 反对(0) 关博兰 | 园豆:152 (初学一级) | 2017-05-09 15:43

@关博兰: 这个不好说,看机器性能的,但我估计你是不是理解错了需求?怎么可能要求一次性初始化3kw后再发出去?一般这种场景也是中间加个缓冲,一边往里面写一边从里面抽往redis里写。

支持(0) 反对(0) Daniel Cai | 园豆:10424 (专家六级) | 2017-05-09 17:42
0

在Redis中字符串类型的Value最多可以容纳的数据长度是512M 

具体见官方文档:https://redis.io/topics/data-types

狼爷 | 园豆:1204 (小虾三级) | 2017-05-10 11:06
0

崩溃时应该调试看在哪, 如果是win32程序, 进程默认最大内存是2G, 另外还有exe等系统其他模块需要消耗
当使用超过这个数量就会崩溃
你可以先去掉redis相关的, 先确认是哪的限制

Yofoo | 园豆:394 (菜鸟二级) | 2020-11-06 17:54
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册