MySQL proxy Learning (III)-Architecture

Source: Internet
Author: User

MySQL proxy architecture: multithreading + libevent + glib2

From the previous content, we have confirmed that the accept process is completed by the main thread, and it creates a con-> client event connected to the client; it then creates a con-> server to connect to the MySQL server in the background. If the FD cannot be written, network_socket_error_retry is returned in proxy_connect_server, and wait_for_event (con-> server, ev_write, null) is called. This macro plays an important role, some code is as follows:

#define WAIT_FOR_EVENT(ev_struct, ev_type, timeout) \event_set(&(ev_struct->event), ev_struct->fd, ev_type, network_mysqld_con_handle, user_data); \chassis_event_add(srv, &(ev_struct->event));case CON_STATE_CONNECT_SERVER:switch ((retval = plugin_call(srv, con, con->state))) {case NETWORK_SOCKET_SUCCESS:/** * hmm, if this is success and we have something in the clients send-queue * we just send it out ... who needs a server ? */if ((con->client != NULL && con->client->send_queue->chunks->length > 0) &&      con->server == NULL) {/* we want to send something to the client */con->state = CON_STATE_SEND_HANDSHAKE;} else {g_assert(con->server);}break;case NETWORK_SOCKET_ERROR_RETRY:if (con->server) {/** * we have a server connection waiting to begin writable */WAIT_FOR_EVENT(con->server, EV_WRITE, NULL);NETWORK_MYSQLD_CON_TRACK_TIME(con, "wait_for_event::connect_server");return;} else {/* try to get a connection to another backend, * * setting ostate = CON_STATE_INIT is a hack to make sure * the loop is coming back to this function again */ostate = CON_STATE_INIT;}break;        …

We can see that wait_for_event modified its previous event, set the callback function to network_mysqld_con_handle, and then call chassis_event_add

void chassis_event_add(chassis *chas, struct event *ev) {chassis_event_op_t *op = chassis_event_op_new();op->type = CHASSIS_EVENT_OP_ADD;op->ev   = ev;g_async_queue_push(chas->threads->event_queue, op);send(chas->threads->event_notify_fds[1], C("."), 0); /* ping the event handler */}

We can see that the modified event is pushed to the queue Chas-> threads-> event_queue through the g_async_queue_push interface of glib2, then write a character to the file descriptor Chas-> threads-> event_policy_fds [1] (Do you still remember what this will do? -- Chassis_event_threads_init_thread). We created a pair of Descriptor [0] readable and [1] writable during initialization, And the readable callback function is: chassis_event_handle. All threads Listen to the event corresponding to this FD, so when the current thread sends (Chas-> threads-> event_policy_fds [1],
C (". "), 0), it will obviously wake up all other threads (including itself) and enter chassis_event_handle, now we can also guess that the callback function is about to get the event pushed from CHAS-> threads-> event_queue, and then listen to the event by it (the currently running thread, in this way, when this event is available, the thread will call network_mysqld_con_handle to process the current state. The Code is as follows:

void chassis_event_handle(int G_GNUC_UNUSED event_fd, short G_GNUC_UNUSED events, void *user_data) {chassis_event_thread_t *event_thread = user_data;struct event_base *event_base = event_thread->event_base;chassis *chas = event_thread->chas;chassis_event_op_t *op;char ping[1024];guint received = 0;gssize removed;while ((op = g_async_queue_try_pop(chas->threads->event_queue))) {chassis_event_op_apply(op, event_base);chassis_event_op_free(op);received++;}/* the pipe has one . per event, remove as many as we received */while (received > 0 &&        (removed = recv(event_thread->notify_fd, ping, MIN(received, sizeof(ping)), 0)) > 0) {received -= removed;}}

It looks a bit like a "surprise group", but this is actually the proxy's intention, because when there are multiple client con concurrencies, at this time, there will be multiple different con states, they are waiting to enter their next state, at this time, the Group will be able to make all threads to get the first event of the current queue, respectively, that is to say, this may make every thread process different con at the same time. [A little dizzy, in fact, is to let every thread run (say it is not said)], the entire MySQL proxy framework and the main process is shown in:

Figure 2 MySQL proxy Architecture

From figure 2, we can see the general START process of the MySQL proxy and the three most important callback functions in the system: network_mysqld_con_accept, chassis_event_handle, network_mysqld_con_handle; and their call time.

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.