0%

spring boot集成hbase

关键配置

参考源码:HbaseProperties,HbaseAutoConfiguration,缺少配置启动报错.

spring:
  data:
    hbase:
      quorum: 192.168.41.128:2181
      rootDir: file:///root/hbase/rootdir
      nodeParent: /hbase

使用

@Autowired
private HbaseTemplate hbaseTemplate;

问题

默认pom配置会存在日志包和servlet包冲突问题:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>com.spring4all</groupId>
        <artifactId>spring-boot-starter-hbase</artifactId>
        <version>1.0.0.RELEASE</version>
    </dependency>
    
    <dependency>
        <groupId>org.apache.hbase</groupId>
        <artifactId>hbase-client</artifactId>
        <version>1.2.12</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

解决办法

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>com.spring4all</groupId>
        <artifactId>spring-boot-starter-hbase</artifactId>
        <version>1.0.0.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.apache.hbase</groupId>
        <artifactId>hbase-client</artifactId>
        <version>1.2.12</version>
        <exclusions>
            <exclusion>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>log4j-over-slf4j</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
            </exclusion>
            <!--<exclusion>-->
                <!--<groupId>com.google.guava</groupId>-->
                <!--<artifactId>guava</artifactId>-->
            <!--</exclusion>-->
        </exclusions>
    </dependency>


    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

假设有这么一段html:

<div class="post-content">
    <h1>Title</h1>
    <p>Subtitle</p>
    <img src="a.jpg">
    <div>
        <a href="example.html">Goto</a>
    </div>
    Bare text
    <br>
    <!-- this is html comment -->
    <p>Bottom</p>            
</div>

child::*

节点的所有子元素,如//div[@class="post-content"]/*,结果:

<h1>Title</h1>
<p>Subtitle</p>
<img src="a.jpg">
<div>
    <a href="example.html">Goto</a>
</div>
<br>
<p>Bottom</p>

可以看到,这里只选择了有标签名的节点,不在标签内的Bare text和注释都被过滤了。

child::text()

节点的所有文本,如//div[@class="post-content"]/text(),结果:

Bare text

child::node()

节点下的所有内容,不论是标签还是文本还是其他,//div[@class="post-content"]/node(),结果:

Title

Subtitle

Bare text

Bottom

原样输出了其下的所有内容。

原文链接

索引结构——B+树

回表查询

InnoDB 引擎中使用的是聚簇索引,其主索引的实现树中的叶子结点存储的是完整的数据记录,而辅助索引中存储的则只是辅助键和主键的值。

索引覆盖

如果索引已经包含了所有满足查询需要的数据,这时我们称之为覆盖索引(Covering Index),这时就不再需要回表操作。

最左匹配

一个查询可以只使用索引中的一部分,更准确地说是最左侧部分(最左优先),这就是传说中的最左匹配原则。

即最左优先,如:

  • 如果有一个 2 列的索引 (col1,col2),则相当于已经对 (col1)、(col1,col2) 上建立了索引;
  • 如果有一个 3 列索引 (col1,col2,col3),则相当于已经对 (col1)、(col1,col2)、(col1,col2,col3) 上建立了索引;但是 (col2,col3) 上并没有。

索引下推

对索引中包含的字段先做判断,过滤掉不符合条件的记录,减少回表字数。

建立索引原则

  • 原文链接
  • 最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
  • =in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式。
  • 尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0;
  • 索引列不能参与计算,保持列干净,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本太大。所以语句应该写成create_time = unix_timestamp(’2014-05-29’)
  • 尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。

查询优化神器 - explain命令

参考链接

public class Dom4jTest {

    public static void main(String[] args) throws DocumentException {
        String svgURI = System.getProperty("user.dir") + "/test.svg";
        SAXReader reader = new SAXReader();
        File file = new File(svgURI);
        Document document = reader.read(file);
        Element root = document.getRootElement();
        List<Element> childElements = root.elements();

        for (Element child : childElements) {
            if ("g".equals(child.getQName().getName())) {
                List<Element> gElements = child.elements();
                for (Element gEle : gElements) {
                    if ("g".equals(gEle.getQName().getName())) {
                        List<Element> elements = gEle.elements();
                        for (Element e : elements) {
                            if ("dfg:desc".equals(e.getQName().getName())) {
                                System.out.println(e.getText());
                            }
                        }
                    }
                }
            }
        }
    }
}

<!-- SVG解析包 -->
<dependency>
    <groupId>org.apache.xmlgraphics</groupId>
    <artifactId>batik-all</artifactId>
    <version>1.12</version>
    <type>pom</type>
</dependency>
<svg>
  <rect x="1" y="1" width="1198" height="598"
        fill="none" stroke="blue" stroke-width="1" />

  <path d="M200,300 Q400,50 600,300 T1000,300"
        fill="none" stroke="red" stroke-width="5"  />
  <g fill="black" >
    <circle cx="200" cy="300" r="10"/>
    <circle cx="600" cy="300" r="10"/>
    <circle cx="1000" cy="300" r="10"/>
  </g>
  <g fill="#888888" >
    <circle cx="400" cy="50" r="10"/>
    <circle cx="800" cy="550" r="10"/>
  </g>
  <path d="M200,300 L400,50 L600,300 L800,550 L1000,300"
        fill="none" stroke="#888888" stroke-width="2" />
</svg>
//You first load the XML as a Document:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("image.svg");
//Then you use XPath to select the desired nodes. The expression below selects the contents of the d attributes of all the path elements inside the file:
String xpathExpression = "//path/@d";
//Now we can instantiate the XPath processor and compile the expression:
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
XPathExpression expression = xpath.compile(xpathExpression);
//Since the expected result is a node-set (two strings), we evaluate the expression on the SVG document using XPathConstants.NODESET as the second parameter:
NodeList svgPaths = (NodeList)expression.evaluate(document, XPathConstants.NODESET);
//From there you can extract the first set of path data using:
svgPaths.item(0).getNodeValue();