HBase1.0.0 the request processing flow analysis of source code analysis take a put operation as an example (ii)
1. By mutate(put) Adding a single put operation to the buffer operation, these buffering operations are actually a collection of a list of the parent class of the put. As follows:
privatenew LinkedList<>(); writeAsyncBuffer.add(m);
When writeAsyncBuffer full or an artificial call to the backgroundflushcommits operation is made, the operation in the buffer pool is executed.
2. backgroundFlushCommits(boolean synchronous) perform operation in the buffer pool, in fact, he is not to deal with the response of the operation, but to delegate to a AsyncProcess specific response operation execution, the class is to simulate an asynchronous processing of a continuous request stream class. Here are some of the main things that happen:
Ap.submit (TableName, Writeasyncbuffer, true , null , false ); Map<servername, multiaction<row>> actionsbyserver = new HashMap<Se Rvername, multiaction<row>> (); list<action<row>> retainedactions = new Arraylist<action<row >> (Rows.size ()); Addaction (Loc.getservername (), Regionname, Action, Actionsbyserver, Noncegroup return
submitmultiactions (TableName, Retainedactions, Noncegroup, callback, null , Needresults, Locationerrors, Locationerrorrows, actionsbyserver, pool);
The following are mainly the following several things summarized here:
* Encapsulation of put operations, encapsulated as action
* Find the Regionserver of each operation corresponding to the ServerName-> Multiaction key value pair, then continue the submit
3. In the submitMultiActions method, the author uses a Asyncrequestfutureimpl implementation to save the resulting data
AsyncRequestFutureImpl<CResult> ars = createAsyncRequestFuture( tableName, retainedActions, nonceGroup, pool, callback, results, needResults);
4. The function sendmultiaction in the class Ars sendMultiAction is the place where the final real logical layer is called, and the complete function is as follows:
Private void sendmultiaction(Map<servername, Multiaction<row>> actionsbyserver,intNumattempt, List<action<row>> Actionsforreplicathread,BooleanReusethread) {//Run The last item on the same thread if we is already on a send thread. //We hope the most of the time it would be is the only item and so We can cut down on threads. intactionsremaining = Actionsbyserver.size ();//This iteration are by server (the Hregionlocation comparator are by server portion only). for(Map.entry<servername, Multiaction<row>> e:actionsbyserver.entryset ()) {ServerName Server = E.getkey (); multiaction<row> multiaction = E.getvalue (); Inctaskcounters (Multiaction.getregions (), server); collection<? Extends runnable> runnables = getnewmultiactionrunnable (server, multiaction, numattempt);//Make sure we correctly count the number of runnables before we try to reuse the send //thread, in case we had to split the request into different runnables because of Backoff if(Runnables.size () > Actionsremaining) {actionsremaining = Runnables.size (); }//Run all the Runnables for(Runnable runnable:runnables) {if(--actionsremaining = =0) && Reusethread) {runnable.run (); }Else{Try{Pool.submit (runnable); }Catch(Rejectedexecutionexception Ree) {//This should never happen. But as the pool was provided by the end user, let's secure //This a little.Dectaskcounters (Multiaction.getregions (), server); Log.warn ("#"+ ID +The task was rejected by the pool. This is unexpected. "+"Server is"+ Server.getservername (), REE);//We ' re likely to fail again, but this would increment the attempt counter, so it would //Finish.Receiveglobalfailure (multiaction, Server, numattempt, REE); } } } }if(Actionsforreplicathread! =NULL) {startwaitingforreplicacalls (actionsforreplicathread); } }
function is very long, but the logic of doing things is relatively clear, from the code can be seen, the processing logic of the program is based on Regionserver to differentiate, each operation is encapsulated into a running task (singleserverrequestrunnable), It is then executed in turn using the ready-made pool.
It is necessary to post the run function of the task they are constructing to study the following, from the run function we can see the real logic of the request:
MultiResponse res; MultiServerCallable<Row> callable = createCallable(server, tableName, multiAction); res = createCaller(callable).callWithoutRetries(callable, timeout); receiveMultiAction(multiAction, server, res, numAttempt);
Each task communicates with the server through the RPC framework of HBase and gets the returned results. At this point, the client's put operation of the process is over, as to the specific RPC side how to implement the relevant content, follow-up blog continue to pay attention to.
Summarize
1. Client has a caching mechanism, batch processing
2. The default put processing is asynchronous
3.Put Finally, according to Regionserver respectively RPC processing
HBase1.0.0 the request processing flow analysis of source code analysis take a put operation as an example (ii)