In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)05/31 Report--
CoralCache is a middleware to improve the availability of micro-services. in view of this problem, this article introduces the corresponding analysis and solutions in detail, hoping to help more partners who want to solve this problem to find a more simple and easy way.
When there is a problem with the database, it can be downgraded to query data from the locally cached data. CoralCache is such a middleware to improve the availability of micro-services.
Background
In some scenarios, the microservice relies on some configuration items or a small amount of data in the database, but when there is something wrong with the database itself, even if the amount of data is small, the service will not work properly. Therefore, we need to consider a scenario that can support global data with full volume and few changes. When something goes wrong in the database, it can be degraded to query data from the locally cached data. CoralCache is such a middleware to improve the availability of micro-services.
Architecture
The CoralCache middleware architecture is shown in the following figure. With @ EnableLocal annotation to enable the function, the configured table data is loaded into memory at one time after the application is started, and the logical structure of the data in memory is the same as that in the database.
Figure 1. Architecture diagram
Expression evaluation engine
The principle of the in-memory query engine is that after the database query degradation occurs, Intercepter transfers the intercepted original SQL into the query engine. After parsing the SQL, the query engine gets the table name, column name and where conditional expression, traverses the data rows of the corresponding table in the InnerDB, and calculates the result through the expression evaluation engine. If the result is true, it is added to the result set and finally returned to the caller.
The structure of the calculation engine is shown in the following figure. After converting the where conditional expression into a suffix expression, the suffix expression is traversed in turn, and the operands are directly put into the stack when encountered, and several operands are loaded according to the operands required by the operator.
Figure 2. Expression evaluation engine structure
Then it is calculated according to the operator and the popup operands. Different operators correspond to different calculation methods, and the calculated results are re-loaded into the stack as operands until traversal is completed. The core calculation process code is as follows:
Public Object calc (Expression where, InnerTable table, InnerRow row) {try {postTraversal (where);} catch (Exception e) {log.warn ("calc error: {}", e.getMessage ()); return false } for (ExprObj obj: exprList) {switch (obj.exprType ()) {case ITEM: stack.push (obj); break; case BINARY_OP: {ExprObj result = calcBinaryOperation (ExprOperation) obj). GetOperationType (), table, row) Stack.push (result); break;} case UNARY_OP: {ExprObj result = calcSingleOperation (ExprOperation) obj). GetOperationType (), table, row); stack.push (result); break } case FUNCTION_OP: {ExprObj result = calcFunctionOperation (ExprOperation) obj). GetOperationType (), table, row); stack.push (result); break;} default: break }} return stack.pop ();} implementation of logical operations of common operators
The common operators in logic are =, =, and so on, all of which require two operands and the return value is of Boolean type.
Public ExprItem logicalCalculus (InnerTable table, InnerRow row, LogicalOperation logicalOperation) {ExprObj second = stack.pop (); ExprObj first = stack.pop (); ExprItem result = new ExprItem (); result.setItemType (ItemType.T_CONST_OBJ); Obj firstObj = getObj ((ExprItem) first, table, row); Obj secondObj = getObj ((ExprItem) second, table, row); boolean value = logicalOperation.apply (firstObj, secondObj) Result.setValue (new Obj (value, ObjType.BOOL)); return result;}
An example is shown with the implementation of "=":
Private ExprObj calcBinaryOperation (OperationType type, InnerTable table, InnerRow row) {ExprObj result = null; switch (type) {case T_OP_EQ: result = logicalCalculus (table, row, (a, b)-> ObjUtil.eq (a, b)); / / equal to the implementation of the symbol break;. Default: break;} return result;} public class ObjUtil {private static ObjType resultType (ObjType first, ObjType second) {return ObjType.RESULT_TYPE [first.ordinal ()] [second.ordinal ()];} public static boolean eq (Obj first, Obj second) {ObjType type = resultType (first.getType (), second.getType ()) Switch (type) {case LONG: {long firstValue = first.getValueAsLong (); long secondValue = second.getValueAsLong (); return firstValue = = secondValue;} case DOUBLE: {double firstValue = first.getValueAsDouble (); double secondValue = second.getValueAsDouble () Return Double.compare (firstValue, secondValue) = = 0;} case TIMESTAMP: {java.util.Date firstValue = first.getValueAsDate (); java.util.Date secondValue = first.getValueAsDate (); return firstValue.compareTo (secondValue) = = 0;}. Default: break;} throw new UnsupportedOperationException (first.getType () + "and" + second.getType () + "not support'= 'operation.");}} Mathematical Operation
The flow of mathematical and logical operations is the same, except that the result is a numeric type.
LIKE operator
In addition to the logical and mathematical operations mentioned above, the special operator LIKE for fuzzy matching is also supported.
LIKE expression syntax
Common uses are as follows
LIKE 'HUAWEI' matches a string that ends in HUAWEI
LIKE "HUAWEI%" matches a string that begins with HUAWEI
"LIKE" matches strings that start with "A" and end with "Z"
LIKE "axib" ditto
LIKE "% [0-9]%" matches a string containing numbers
LIKE "% [a murz]%" matches a string containing lowercase letters
LIKE'% [! 0-9]% 'matches a string without numbers
? And _ both represent a single character
The solution for implementing LIKE in JAVA is to convert the schema of LIKE to a regular expression in JAVA.
LIKE lexical definition expr: = wild-card + expr | wild-char + expr | escape + expr | string + expr | "" wild-card: =% wild-char: = _ escape: = [% | _] string: = [^% _] + (One or > more characters that are not wild-card or wild-char) defines Token class public abstract class Token {private final String value; public Token (String value) {this.value = value } public abstract String convert (); public String getValue () {return value;}} public class ConstantToken extends Token {public ConstantToken (String value) {super (value);} @ Override public String convert () {return getValue ();}} public class EscapeToken extends Token {public EscapeToken (String value) {super (value) } @ Override public String convert () {return getValue ();}} public class StringToken extends Token {public StringToken (String value) {super (value);} @ Override public String convert () {return Pattern.quote (getValue ());}} public class WildcardToken extends Token {public WildcardToken (String value) {super (value) } @ Override public String convert () {return ". *";}} public class WildcharToken extends Token {public WildcharToken (String value) {super (value);} @ Override public String convert () {return ".";}} create Lexer (Tokenizer) public class Tokenizer {private Collection patterns = new LinkedList () Public Tokenizer add (String regex, Function creator) {this.patterns.add (new Tuple (Pattern.compile (regex), creator); return this;} public Collection tokenize (String clause) throws RuntimeException {Collection tokens = new ArrayList (); String copy = String.copyValueOf (clause.toCharArray ()); int position = 0; while (! copy.equals (")) {boolean found = false For (Tuple tuple: this.patterns) {Pattern pattern = (Pattern) tuple.getFirst (); Matcher m = pattern.matcher (copy); if (m.find ()) {found = true; String token = m.group (1); Function fn = (Function) tuple.getSecond () Tokens.add (fn.apply (token)); copy = m.replaceFirst (""); position + = token.length (); break;}} if (! found) {throw new RuntimeException ("Unexpected sequence found in input string, at" + position) }} return tokens }} create a LIKE to regular expression transformation mapping public class LikeTranspiler {private static Tokenizer TOKENIZER = new Tokenizer () .add ("^ (\ [[^] *]])", ConstantToken::new) .add ("^ (%)", WildcardToken::new) .add ("^ (_)", WildcharToken::new) .add ("^ ([^\ [\]%]%] +)" StringToken::new) Public static String toRegEx (String pattern) throws ParseException {StringBuilder sb = new StringBuilder () .append ("^"); for (Token token: TOKENIZER.tokenize (pattern)) {sb.append (token.convert ());} return sb.append ("$") .toString ();}}
Directly call the toRegEx method of LikeTranspiler to convert the LIKE syntax to a regular expression in JAVA.
Private ExprObj calcBinaryOperation (OperationType type, InnerTable table, InnerRow row) {ExprObj result = null; switch (type) {. . . Case T_OP_LIKE: result = logicalCalculus (table, row, (a, b)-> ObjUtil.like (a, b)); break;. . . } return result;} public static boolean like (Obj first, Obj second) {Assert.state (first.getType () = = ObjType.STRING, OperationType.T_OP_LIKE + "only support STRING."); Assert.state (second.getType () = = ObjType.STRING, OperationType.T_OP_LIKE + "only support STRING."); String firstValue = (String) first.getRelValue (); String secondValue = (String) second.getRelValue () String regEx = LikeTranspiler.toRegEx (secondValue); return Pattern.compile (regEx) .matcher (firstValue). Matches ();}
By creating a lexical analyzer and converting it using this method, we can prevent a clause like LIKE from being converted to the regular expression% abc [%]%, which should match any substring within it, which will match the substring or any string. Abc%.abc [.] .abc.abc .
Type calculation conversion
Different data types need to be transformed into the next two-dimensional array.
/ / different types of calculated types ObjType [] [] RESULT_TYPE = {/ / UNKNOWN BYTE SHORT INT LONG FLOAT DOUBLE DECIMAL BOOL DATE TIME TIMESTAMP STRING NULL {UNKNOWN, UNKNOWN}, / / UNKNOWN {UNKNOWN, LONG, DOUBLE, DOUBLE DECIMAL, BOOL, UNKNOWN, LONG, UNKNOWN}, / / BYTE {UNKNOWN, LONG, DOUBLE, DOUBLE, DECIMAL, BOOL, UNKNOWN, LONG, UNKNOWN}, / / SHORT {UNKNOWN, LONG, DOUBLE, DOUBLE, DECIMAL, BOOL, UNKNOWN, LONG UNKNOWN}, / / INT {UNKNOWN, LONG, DOUBLE, DOUBLE, DECIMAL, BOOL, UNKNOWN, LONG, UNKNOWN}, / / LONG {UNKNOWN, DOUBLE, DECIMAL, BOOL, UNKNOWN, DOUBLE, UNKNOWN}, / / FLOAT {UNKNOWN, DOUBLE, DOUBLE DOUBLE, DOUBLE, DECIMAL, BOOL, UNKNOWN, DOUBLE, UNKNOWN}, / / DOUBLE {UNKNOWN, DECIMAL, UNKNOWN, DECIMAL, UNKNOWN}, / / DECIMAL {UNKNOWN, BOOL, UNKNOWN, BOOL, UNKNOWN} / / BOOL {UNKNOWN, TIMESTAMP, UNKNOWN}, / / DATE {UNKNOWN, TIMESTAMP, UNKNOWN}, / / TIME {UNKNOWN, TIMESTAMP, UNKNOWN}, / / TIMESTAMP {UNKNOWN, LONG, LONG, LONG LONG, DOUBLE, DOUBLE, DECIMAL, BOOL, TIMESTAMP, STRING, UNKNOWN}, / / STRING {UNKNOWN, UNKNOWN}, / / NULL}
Click follow to learn about Huawei's new cloud technology for the first time.
This is the answer to the middleware CoralCache question about improving the usability of micro-services. I hope the above content can be of some help to you. If you still have a lot of doubts to be solved, you can follow the industry information channel for more related knowledge.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.