Пример #1
0
int main(int argc, char **argv)
{
	parse_cmd(argc, argv);

#ifdef HAVE_JEMALLOC
	if (jemalloc_limit) {
		memory_used_fn = jemalloc_size_allocated;
	}
#endif

	if (!memory_used_fn) {
		memory_used_fn = zmalloc_used_memory;
	}

	zmalloc_enable_thread_safeness();

	pthread_t threads[thread_count];

	for (int i = 0; i < thread_count; i++) {
		if (0 != pthread_create(&threads[i], 0, thread_worker, 0)) {
			fprintf(stderr, "error while creating thread\n");
			return -1;
		}
	}

	char size_human_buf[1024];
	char rss_human_buf[1024];

	for (;;) {
		sleep(1);
		size_t rss = zmalloc_get_rss();
		size_t used = memory_used_fn();
		mem_cpu_to_human(used, size_human_buf, 1024);
		mem_cpu_to_human(rss, rss_human_buf, 1024);
		printf("memory_used %s, rss %s, fragmentation ratio %f\n", size_human_buf, rss_human_buf, zmalloc_get_fragmentation_ratio(rss));
	}

	return 0;
}
Пример #2
0
int main (int argc, char **argv) {
    struct timeval tv;

    // 初始化相关环境变量与库
#ifdef INIT_SETPROCTITLE_REPLACEMENT
    spt_init(argc, argv);
#endif

    // 设置当前的`locale`命令里的内容
    setlocale(LC_COLLATE, "");

    // 自动分配线程安全
    zmalloc_enable_thread_safeness();

    // 设置自动分配函数句柄(out of memory)
    zmalloc_set_oom_handler(redisOutOfMemoryHandler);

    // 时间异或pid生成随机数种子
    srand(time(NULL) ^ getpid());
    gettimeofday(&tv, NULL);

    // 设置字典hash值种子
    dictSetHashFunctionSeed(tv.tv_sec ^ tv.tv_usec ^ getpid());

    // 定点模式检测
    server.sentinel_mode = checkForSentinelMode(argc, argv);

    // 初始化服务配置
    initServerConfig();

    // 定点模式处理
    if (server.sentinel_mode) {
        printf("deal with sentinel mode\n");
    }

    if (argc >= 2) {
        int j = 1;
        // init empty string
        sds options = sdsempty();
        char *configfile = NULL;

        if (strcmp(argv[1], "-v") == 0 ||
            strcmp(argv[1], "--version") == 0) version();
        if (strcmp(argv[1], "--help") == 0 ||
            strcmp(argv[1], "-h") == 0) usage();
        if (strcmp(argv[1], "--test-memory") == 0) {
            if (argc == 3) {
                // 内存测试还未完全写完
                memtest(atoi(argv[2]), 50);
                exit(0);
            } else {
                fprintf(stderr, "Please specify the amount of memory to test in megabytes.\n");
                fprintf(stderr, "Example: ./redis-server --test-memory 4096\n\n");
                exit(1);
            }
        }

        /*
         * 第一个参数为'--'开头, j始终为1
         * 第一个参数不为'--'开头, j始终为2
         *
         */

        // j为1,第1个参数不是'--'开头的是配置文件
        if (argv[j][0] != '-' || argv[j][1] != '-') {
            configfile = argv[j++];
        }

        // 配置文件参数后还有内容
        while (j != argc) {
            // 所有参数有包括'--'开头的参数
            if (argv[j][0] == '-' && argv[j][1] == '-') {
                if (sdslen(options)) options = sdscat(options, "\n");
                options = sdscat(options, " ");
            } else {
                // append new string, 转义特殊字符, return new pointer
                options = sdscatrepr(options, argv[j], strlen(argv[j]));
                options = sdscat(options, " ");
            }
            j++;
        }

        if (server.sentinel_mode && configfile && *configfile == '-') {
            printf("need redis log\n");
            exit(1);
        }

        if (configfile) {
            server.configfile = getAbsolutePath(configfile);
        }
        resetServerSaveParams();
        loadServerConfig(configfile, options);
        sdsfree(options);
    } else {
        printf("warning: no config file specified\n");
    }

    // 后台模式
    if (server.daemonize) {
        daemonize();
    }

    // init server
    initServer();

    printf("redis done\n");
    return 0;
}
Пример #3
0
Файл: vm.c Проект: Elbandi/redis
void vmInit(void) {
    off_t totsize;
    int pipefds[2];
    size_t stacksize;
    struct flock fl;

    if (server.vm_max_threads != 0)
        zmalloc_enable_thread_safeness(); /* we need thread safe zmalloc() */

    redisLog(REDIS_NOTICE,"Using '%s' as swap file",server.vm_swap_file);
    /* Try to open the old swap file, otherwise create it */
    if ((server.vm_fp = fopen(server.vm_swap_file,"r+b")) == NULL) {
        server.vm_fp = fopen(server.vm_swap_file,"w+b");
    }
    if (server.vm_fp == NULL) {
        redisLog(REDIS_WARNING,
            "Can't open the swap file: %s. Exiting.",
            strerror(errno));
        exit(1);
    }
    server.vm_fd = fileno(server.vm_fp);
    /* Lock the swap file for writing, this is useful in order to avoid
     * another instance to use the same swap file for a config error. */
    fl.l_type = F_WRLCK;
    fl.l_whence = SEEK_SET;
    fl.l_start = fl.l_len = 0;
    if (fcntl(server.vm_fd,F_SETLK,&fl) == -1) {
        redisLog(REDIS_WARNING,
            "Can't lock the swap file at '%s': %s. Make sure it is not used by another Redis instance.", server.vm_swap_file, strerror(errno));
        exit(1);
    }
    /* Initialize */
    server.vm_next_page = 0;
    server.vm_near_pages = 0;
    server.vm_stats_used_pages = 0;
    server.vm_stats_swapped_objects = 0;
    server.vm_stats_swapouts = 0;
    server.vm_stats_swapins = 0;
    totsize = server.vm_pages*server.vm_page_size;
    redisLog(REDIS_NOTICE,"Allocating %lld bytes of swap file",totsize);
    if (ftruncate(server.vm_fd,totsize) == -1) {
        redisLog(REDIS_WARNING,"Can't ftruncate swap file: %s. Exiting.",
            strerror(errno));
        exit(1);
    } else {
        redisLog(REDIS_NOTICE,"Swap file allocated with success");
    }
    server.vm_bitmap = zcalloc((server.vm_pages+7)/8);
    redisLog(REDIS_VERBOSE,"Allocated %lld bytes page table for %lld pages",
        (long long) (server.vm_pages+7)/8, server.vm_pages);

    /* Initialize threaded I/O (used by Virtual Memory) */
    server.io_newjobs = listCreate();
    server.io_processing = listCreate();
    server.io_processed = listCreate();
    server.io_ready_clients = listCreate();
    pthread_mutex_init(&server.io_mutex,NULL);
    pthread_mutex_init(&server.io_swapfile_mutex,NULL);
    server.io_active_threads = 0;
    if (pipe(pipefds) == -1) {
        redisLog(REDIS_WARNING,"Unable to intialized VM: pipe(2): %s. Exiting."
            ,strerror(errno));
        exit(1);
    }
    server.io_ready_pipe_read = pipefds[0];
    server.io_ready_pipe_write = pipefds[1];
    redisAssert(anetNonBlock(NULL,server.io_ready_pipe_read) != ANET_ERR);
    /* LZF requires a lot of stack */
    pthread_attr_init(&server.io_threads_attr);
    pthread_attr_getstacksize(&server.io_threads_attr, &stacksize);

    /* Solaris may report a stacksize of 0, let's set it to 1 otherwise
     * multiplying it by 2 in the while loop later will not really help ;) */
    if (!stacksize) stacksize = 1;

    while (stacksize < REDIS_THREAD_STACK_SIZE) stacksize *= 2;
    pthread_attr_setstacksize(&server.io_threads_attr, stacksize);
    /* Listen for events in the threaded I/O pipe */
    if (aeCreateFileEvent(server.el, server.io_ready_pipe_read, AE_READABLE,
        vmThreadedIOCompletedJob, NULL) == AE_ERR)
        oom("creating file event");
}
Пример #4
0
void vmInit(void) {
    off totsize;
    int pipefds[2];
    size_t stacksize;
#ifndef _WIN32
    struct flock fl;
#endif

    if (server.vm_max_threads != 0)
        zmalloc_enable_thread_safeness(); /* we need thread safe zmalloc() */

    redisLog(REDIS_NOTICE,"Using '%s' as swap file",server.vm_swap_file);
    /* Try to open the old swap file, otherwise create it */
    if ((server.vm_fp = fopen(server.vm_swap_file,"r+b")) == NULL) {
        server.vm_fp = fopen(server.vm_swap_file,"w+b");
    }

    if (server.vm_fp == NULL) {
        redisLog(REDIS_WARNING,
            "Can't open the swap file: %s. Exiting.",
            strerror(errno));
        exit(1);
    }
    server.vm_fd = fileno(server.vm_fp);
    /* Lock the swap file for writing, this is useful in order to avoid
     * another instance to use the same swap file for a config error. */
#ifdef _WIN32

    // LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0)
    if(!LockFile((HANDLE) _get_osfhandle(server.vm_fd), (0x40000001), 0, 1, 0) ) {
        redisLog(REDIS_WARNING,
            "Can't lock the swap file at '%s': %s. Make sure it is not used by another Redis instance.", server.vm_swap_file, strerror(errno));
        WSACleanup();
        exit(1);
    }
#else
    fl.l_type = F_WRLCK;
    fl.l_whence = SEEK_SET;
    fl.l_start = fl.l_len = 0;
    if (fcntl(server.vm_fd,F_SETLK,&fl) == -1) {
        redisLog(REDIS_WARNING,
            "Can't lock the swap file at '%s': %s. Make sure it is not used by another Redis instance.", server.vm_swap_file, strerror(errno));
        exit(1);
    }
#endif
    /* Initialize */
    server.vm_next_page = 0;
    server.vm_near_pages = 0;
    server.vm_stats_used_pages = 0;
    server.vm_stats_swapped_objects = 0;
    server.vm_stats_swapouts = 0;
    server.vm_stats_swapins = 0;
    totsize = server.vm_pages*server.vm_page_size;
#ifdef _WIN32
    redisLog(REDIS_NOTICE,"Allocating %lld bytes of swap file",(long long) totsize);
#else
    redisLog(REDIS_NOTICE,"Allocating %lld bytes of swap file",totsize);
#endif
    if (ftruncate(server.vm_fd,totsize) == -1) {
        redisLog(REDIS_WARNING,"Can't ftruncate swap file: %s. Exiting.",
            strerror(errno));
        exit(1);
    } else {
        redisLog(REDIS_NOTICE,"Swap file allocated with success");
    }
    server.vm_bitmap = zcalloc((server.vm_pages+7)/8);
    redisLog(REDIS_VERBOSE,"Allocated %lld bytes page table for %lld pages",
        (long long) (server.vm_pages+7)/8, server.vm_pages);

    /* Initialize threaded I/O (used by Virtual Memory) */
    server.io_newjobs = listCreate();
    server.io_processing = listCreate();
    server.io_processed = listCreate();
    server.io_ready_clients = listCreate();
#ifndef _WIN32
    /* moved to InitSharedObjecsts since they are first time used there */
    pthread_mutex_init(&server.io_mutex,NULL);
    pthread_mutex_init(&server.io_swapfile_mutex,NULL);
#endif
    server.io_active_threads = 0;
    if (pipe(pipefds) == -1) {
        redisLog(REDIS_WARNING,"Unable to intialized VM: pipe(2): %s. Exiting."
            ,strerror(errno));
        exit(1);
    }
    server.io_ready_pipe_read = pipefds[0];
    server.io_ready_pipe_write = pipefds[1];
#ifndef _WIN32
    /* Windows distincts pipe and socket destriptors */
    /* We will use blocking pipe, with peek before blocking read */
    redisAssert(anetNonBlock(NULL,server.io_ready_pipe_read) != ANET_ERR);
#endif
    /* LZF requires a lot of stack */
    pthread_attr_init(&server.io_threads_attr);
    pthread_attr_getstacksize(&server.io_threads_attr, &stacksize);

    /* Solaris may report a stacksize of 0, let's set it to 1 otherwise
     * multiplying it by 2 in the while loop later will not really help ;) */
    if (!stacksize) stacksize = 1;

    while (stacksize < REDIS_THREAD_STACK_SIZE) stacksize *= 2;
    pthread_attr_setstacksize(&server.io_threads_attr, stacksize);

    /* Listen for events in the threaded I/O pipe */
#ifdef _WIN32
    /* Windows fix: need to pass flag that notifies Api that file descriptor is pipe */
    if (aeCreateFileEvent(server.el, server.io_ready_pipe_read, AE_READABLE | AE_PIPE,
        vmThreadedIOCompletedJob, NULL) == AE_ERR)
        oom("creating file event");
#else
    if (aeCreateFileEvent(server.el, server.io_ready_pipe_read, AE_READABLE,
        vmThreadedIOCompletedJob, NULL) == AE_ERR)
        oom("creating file event");
#endif
}
Пример #5
0
int main(int argc, char *argv[]) {
    struct configOption *confOpt;
    char tmpstr[ALLOW_PATH_SIZE] = {""};
    pthread_t ntid;

    g_logdir = NULL;
    g_logF = stderr;
    g_logFInt = STDERR_FILENO;

    setlocale(LC_ALL,"");

    zmalloc_enable_thread_safeness();

    snprintf(tmpstr, ALLOW_PATH_SIZE, "%s/../", argv[0]);
    if (NULL == realpath(tmpstr, g_basedir)) {
        trvExit(0, "获取当前路径失败");
    }

    g_conf = initConfig();

    snprintf(tmpstr, ALLOW_PATH_SIZE, "%s/../conf/default.conf", g_basedir);
    configRead(g_conf, tmpstr);

    if (argc > 1) configRead(g_conf, argv[1]); /* argv[1] 是配置文件路径 */

    if (NULL == g_conf->contents) {
        trvExit(0, "请选择配置文件");
    }

    confOpt = configGet(g_conf, "log", "dir");
    if (confOpt) {
        g_logdir = (char *)zmalloc(confOpt->valueLen+1);
        memcpy(g_logdir, confOpt->value, confOpt->valueLen);
        g_logdir[confOpt->valueLen] = 0x00;
        g_logF = fopen(g_logdir, "a+");
        g_logFInt = fileno(g_logF);
    }

    signal(SIGHUP, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);
    setupSignalHandlers();


    /**
     * 主线程睡眠,等待网络就绪
     * 单独开一个线程处理网路
     */
    pthread_mutex_lock(&g_rootThreadMutex);
    pthread_create(&ntid, NULL, _NTInit, NULL);
    pthread_cond_wait(&g_rootThreadCond, &g_rootThreadMutex);
    pthread_mutex_unlock(&g_rootThreadMutex);


    _STInitPlanet(NULL);


    /* 主线程睡眠,避免退出进程 */
    pthread_cond_wait(&g_rootThreadCond, &g_rootThreadMutex);
    pthread_mutex_unlock(&g_rootThreadMutex);

    return 0;
}