redis学習ノート1
5763 ワード
長い間探していたが、やはりredisのソースコードが楽に見えることに気づいた.だから今年はredisのソースを読んでついでに読書ノートを作ることにしました.ちゃんと記録しておきます.でも今は頭で物を記録するのが嫌になり、noteで覚えるのが好きになりました.っていうか、そんなに頭を使わないと早すぎる認知症にならないかな~~~
一、redisダウンロードコンパイル
ここには何も言うことはない.
使用するバージョンはredis-2.8.17です
1)redis-serverは実行可能プログラム
2)mian関数はredis.c奥
3)srcディレクトリの下でデバッグを変更する場合、makeまたはmake cleanを変更します.makeでいい
main関数から言えばここで2つの部分を先に言います1つはredisの中のコールバック関数でもう1つはredisの中のlogログです
二、redis内のコールバック関数
まずコードを見てください.これはredisの中のコールバック関数を出して修正します
実行結果
zmalloc_default_oom
zmalloc:Out of memory trying to allocate 10 bytes
デフォルトでは、コールバック関数が登録されていない場合zmalloc_が表示されます.oom_handlerはzmalloc_を指すdefault_oom関数の
コールバック関数が登録されている場合は、登録されているコールバック関数が呼び出されます
実行結果
zmalloc_set_oom_handler
redisOutOfMemoryHandler----------:10
redisのコードを見てみましょう
メモリの割り当てに失敗した場合、コールバック関数がトリガーされます.
三、redisのlogログ
redisは単一スレッドなのでredis.cの中のロゴはマルチスレッドになっていません
このようなlogは、ロックがないため、単一スレッドでは速度が速い.しかし、マルチスレッドでは安全ではありません.
下redisのlogリストを簡略化したのは大体そうです
logログがパフォーマンスに影響を及ぼさずに最も速く最も多くのログを書くことができるかについて、
マルチスレッド用ロックは必然的に速度に影響します
ダブルキューを使うのはいいようですが、logの内容をキューに入れることができます.1つのキューはlogを受信し、1つのキューはlogを印刷します.
印刷されたlogキューを受信したlogキューと交換し、この方法を継続する陳碩の「linuxマルチスレッドネットワークプログラミング」で紹介した.
Googleのglogは性能が良いようで、いつglogを見終わってからlogログの実現を討論する時間があります
一、redisダウンロードコンパイル
ここには何も言うことはない.
使用するバージョンはredis-2.8.17です
1)redis-serverは実行可能プログラム
2)mian関数はredis.c奥
3)srcディレクトリの下でデバッグを変更する場合、makeまたはmake cleanを変更します.makeでいい
main関数から言えばここで2つの部分を先に言います1つはredisの中のコールバック関数でもう1つはredisの中のlogログです
二、redis内のコールバック関数
まずコードを見てください.これはredisの中のコールバック関数を出して修正します
/*
redis
*/
#include<stdio.h>
#include<stdlib.h>
static void zmalloc_default_oom(size_t size)
{
printf("zmalloc_default_oom
");
fprintf(stderr, "zmalloc: Out of memory trying to allocate %d bytes
",size);
fflush(stderr);
}
static void (*zmalloc_oom_handler)(size_t) = zmalloc_default_oom;
void zmalloc_set_oom_handler(void (*oom_handler)(size_t))
{
printf("zmalloc_set_oom_handler
");
zmalloc_oom_handler = oom_handler;
}
void redisOutOfMemoryHandler(size_t allocation_size)
{
printf("redisOutOfMemoryHandler------:%d
",allocation_size);
}
int main(void)
{
//zmalloc_set_oom_handler(redisOutOfMemoryHandler);
zmalloc_oom_handler(10);
getchar();
return 0;
}
実行結果
zmalloc_default_oom
zmalloc:Out of memory trying to allocate 10 bytes
デフォルトでは、コールバック関数が登録されていない場合zmalloc_が表示されます.oom_handlerはzmalloc_を指すdefault_oom関数の
コールバック関数が登録されている場合は、登録されているコールバック関数が呼び出されます
int main(void)
{
zmalloc_set_oom_handler(redisOutOfMemoryHandler);
zmalloc_oom_handler(10);
getchar();
return 0;
}
実行結果
zmalloc_set_oom_handler
redisOutOfMemoryHandler----------:10
redisのコードを見てみましょう
int main(int argc, char **argv)
{
struct timeval tv;
/* We need to initialize our libraries, and the server configuration. */
#ifdef INIT_SETPROCTITLE_REPLACEMENT
//
spt_init(argc, argv);
#endif
setlocale(LC_COLLATE,"");
/*
zmalloc_enable_thread_safeness()
, ,
redis , ,
, redis ,
, 。
*/
zmalloc_enable_thread_safeness();
/*
zmalloc_set_oom_handler()
,
,
redisOutOfMemoryHandler 。
*/
zmalloc_set_oom_handler(redisOutOfMemoryHandler);
srand(time(NULL)^getpid());
gettimeofday(&tv,NULL);
dictSetHashFunctionSeed(tv.tv_sec^tv.tv_usec^getpid());
server.sentinel_mode = checkForSentinelMode(argc,argv);
initServerConfig();
..........
}
zmalloc_set_oom_handler
redisOutOfMemoryHandler log , , log。
void *zmalloc(size_t size) {
void *ptr = malloc(size+PREFIX_SIZE);
if (!ptr) zmalloc_oom_handler(size);
#ifdef HAVE_MALLOC_SIZE
update_zmalloc_stat_alloc(zmalloc_size(ptr));
return ptr;
#else
*((size_t*)ptr) = size;
update_zmalloc_stat_alloc(size+PREFIX_SIZE);
return (char*)ptr+PREFIX_SIZE;
#endif
}
メモリの割り当てに失敗した場合、コールバック関数がトリガーされます.
三、redisのlogログ
redisは単一スレッドなのでredis.cの中のロゴはマルチスレッドになっていません
このようなlogは、ロックがないため、単一スレッドでは速度が速い.しかし、マルチスレッドでは安全ではありません.
下redisのlogリストを簡略化したのは大体そうです
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
/* Log levels */
#define REDIS_DEBUG 0
#define REDIS_VERBOSE 1
#define REDIS_NOTICE 2
#define REDIS_WARNING 3
#define REDIS_MAX_LOGMSG_LEN 1024 /* */
void redisLogRaw(int level, const char *msg);
void redisLog(int level, const char *fmt, ...);
/*
verbosity log
log ,log verbosity log
log
*/
struct redisServer {
int verbosity; /* */
char *logfile; /* Path of log file */
};
struct redisServer server; /* server global state */
void redisLog(int level, const char *fmt, ...)
{
// level verbosity
if (level> server.verbosity)
{
return;
}
va_list ap;
char msg[REDIS_MAX_LOGMSG_LEN];
va_start(ap, fmt);
vsnprintf(msg, sizeof(msg), fmt, ap);
va_end(ap);
redisLogRaw(level,msg);
}
void redisLogRaw(int level, const char *msg)
{
#if 1
FILE *fp;
char buf[64];
// int rawmode = (level & REDIS_LOG_RAW);
//int log_to_stdout = server.logfile[0] == '\0';
//level &= 0xff; /* clear flags */
//if (level < server.verbosity) return;
if(server.logfile != NULL)
{
fp=fopen(server.logfile,"a");
}
else
{
fp=stdout;
}
int off;
// struct timeval tv;
//gettimeofday(&tv,NULL);
//off = strftime(buf,sizeof(buf),"%d %b %H:%M:%S.",localtime(&tv.tv_sec));
//snprintf(buf+off,sizeof(buf)-off,"%03d",(int)tv.tv_usec/1000);
//fprintf(fp,"[%d] %s %c %s
",(int)getpid(),buf,c[level],msg);
fprintf(fp," %s
",msg);
fflush(fp);
if(server.logfile != NULL)
{
fclose(fp);
}
#endif
}
int main(void)
{
server.verbosity=2;
server.logfile=NULL;
redisLog(1,"11111111
");
redisLog(2,"22222
");
redisLog(3,"333
");
getchar();
return 0;
}
logログがパフォーマンスに影響を及ぼさずに最も速く最も多くのログを書くことができるかについて、
マルチスレッド用ロックは必然的に速度に影響します
ダブルキューを使うのはいいようですが、logの内容をキューに入れることができます.1つのキューはlogを受信し、1つのキューはlogを印刷します.
印刷されたlogキューを受信したlogキューと交換し、この方法を継続する陳碩の「linuxマルチスレッドネットワークプログラミング」で紹介した.
Googleのglogは性能が良いようで、いつglogを見終わってからlogログの実現を討論する時間があります