Redis study Note 1

Source: Internet
Author: User

After searching for half a day, I found that the source code of redis looks quite comfortable. So I decided to read the redis source code this year and take a reading Note by the way. Make a good record. Now, the more you don't want to use your head to record things, the more you like to note. Will it lead to premature Alzheimer's disease if you don't love your brain ~~~

 

1. Download and compile redis

There's nothing to say here

The version used is the redis-2.8.17

 

1) redis-Server is an executable program

2) The mian function is in redis. C.

3) If you want to modify and debug the "make" or "make clean; make" command in the src directory

 

Starting from the main function, let's talk about two parts. One is the callback function in redis and the other is the log in redis.

Ii. Callback functions in redis

Let's take a look at the code first. This is to take out the callback function in redis and modify it.

/* Redis callback function */# include <stdio. h> # include <stdlib. h> static void zmalloc_default_oom (size_t size) {printf ("zmalloc_default_oom \ n"); fprintf (stderr, "zmalloc: out of memory trying to allocate % d bytes \ n ", size); fflush (stderr);} static void (* zmalloc_oom_handler) (size_t) = zmalloc_default_oom; void Merge (void (* oom_handler) (size_t )) {printf ("bytes \ n"); zmalloc_oom_handler = oom_handler;} void redisoutofmemoryhandler (size_t allocation_size) {printf ("bytes ------: % d \ n", allocation_size );} int main (void) {// zmalloc_set_oom_handler (redisoutofmemoryhandler); zmalloc_oom_handler (10); getchar (); Return 0 ;}

  

Running result

Zmalloc_default_oom

Zmalloc: out of memory trying to allocate 10 bytes

 

We can see that zmalloc_oom_handler points to the zmalloc_default_oom function without registering the callback function by default.

 

If a callback function is registered, the registered callback function is called.

int main(void){    zmalloc_set_oom_handler(redisOutOfMemoryHandler);    zmalloc_oom_handler(10);    getchar();    return 0;}

Running result

Zmalloc_set_oom_handler

Redisoutofmemoryhandler ----------: 10

 

 

Now let's look at the redis code.

 

Int main (INT argc, char ** argv) {struct timeval TV;/* We Need to initialize our libraries, and the server configuration. */# ifdef init_setproctitle_replacement // initialization parameter spt_init (argc, argv); # endifsetlocale (lc_collate, "");/* thread () enables thread security variables for memory allocation management, when memory is allocated, redis calculates a total memory allocation volume, which is a shared resource. Therefore, atomic operations are required. In the memory allocation code of redis, when atomic operations are required, you need to open the thread security variable. */Zmalloc_enable_thread_safeness ();/* zmalloc_set_oom_handler () is a memory allocation error handling. When the desired memory volume cannot be obtained, the redisoutofmemoryhandler function is called. */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 registers the callback function
Redisoutofmemoryhandler is mainly used to print logs. That is, when memory allocation fails, a callback function is triggered to print logs.
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}

The callback function is triggered when memory allocation fails.

 

 

Iii. redis log

Because redis is single-threaded, logs in redis. C are not made into multiple threads.

Such a log is fast in a single thread because there is no lock. However, multithreading is not safe.

This simplifies the redis log statement.

# 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 limit 1024/* default information length */void redislograw (INT level, const char * MSG); void redislog (INT level, const char * FMT ,...); /* verbosity indicates that when the log level is enabled, the log level must be less than or equal to verbosity to write the log; otherwise, the log will not be written */struct redisserver {int verbosity;/* day Log Level */char * logfile;/* path of Log File */}; struct redisserver server;/* server global state */void redislog (INT level, const char * FMT ,...) {// if the level is greater than verbosity, if (level> server is not printed. 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 \ n", (INT) getpid (), Buf, C [level], MSG); fprintf (FP, "% s \ n", MSG); fflush (FP); If (server. logfile! = NULL) {fclose (FP) ;}# endif} int main (void) {server. verbosity = 2; server. logfile = NULL; redislog (1, "11111111 \ n"); redislog (2, "22222 \ n"); redislog (3, "333 \ n "); getchar (); Return 0 ;}

  

 

How can I write the fastest and most logs without affecting performance,

Multi-thread locks will inevitably affect the speed.

The dual-queue method seems quite good. You can put the log Content in the queue. One queue is responsible for receiving logs, and one queue is responsible for printing logs.

The printed log queue is then exchanged with the receiving log queue. Chen Shuo's LINUX multi-thread network programming section describes how to continue with this method.

 

It seems that Google's glog has good performance. When can I read the glog and discuss the implementation of log?

 

Redis study Note 1

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.