栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

表格存储Wide Colum模型使用简介

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

表格存储Wide Colum模型使用简介

文章目录

前言

一、表格存储入门

1.创建实例

 2.创建表

二、Java SDK使用介绍

1.官方示例

2.引入库

3.构建AsyncClient 工具类

3.插入数据

4.获取数据

5.官方最佳实际

三、Wide Cloum 模型介绍

四、表设计

总结




前言

因为学过的知识经常忘记,所以就以博客的方式记录下来,偶尔翻看一下加深一下印象。




一、表格存储入门

快速入门,参考官方文档:快速入门 - 表格存储 Tablestore - 阿里云https://help.aliyun.com/document_detail/27286.html

1.创建实例

进入控制台,选择自己合适的地区,创建实例。这里弹出两种购买方式,一种预留模式和按量模式。这里我选择按量模式,因为购买了资源包,一个月1亿的读写CU。预留模式自行研究。两者的区别的话参考官方文档的产品定价。

 2.创建表

创建实例完成后,点击实例进入实例管理页面。

 点击创建数据表

 

输入表名,以及主键名,第一个主键为分区键,默认情况下,阿里云会自动管理分区,如果需要预分区的话要联系阿里云技术支持。目前一个表最多支持4个主键,创建完成后点击确认即可创建表。



二、Java SDK使用介绍

1.官方示例

GitHub - aliyun/tablestore-examples: Example code for aliyun tablestore.Example code for aliyun tablestore. Contribute to aliyun/tablestore-examples development by creating an account on GitHub.https://github.com/aliyun/tablestore-examples



2.引入库


    4.0.0

    com.jackxue
    tablestore-study
    pom
    1.0-SNAPSHOT
    
        wide-column
        v2
    

    
        UTF-8
    

    
        
            com.aliyun.openservices
            tablestore
            5.4.0
        
        
            commons-io
            commons-io
            2.4
        
        
            org.slf4j
            slf4j-log4j12
            1.7.25
        
        
            log4j
            log4j
            1.2.17
        
    
    
    



3.构建AsyncClient 工具类
package com.jackxue.v2.util;


import com.alicloud.openservices.tablestore.AsyncClient;
import com.alicloud.openservices.tablestore.TunnelClient;
import com.google.gson.Gson;
import org.apache.commons.io.IOUtils;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class TableStoreUtils {
    private static AsyncClient asyncClient;
    private static TunnelClient tunnelClient;
    private static Conf conf;

    class Conf {
        private String endpoint;
        private String accessId;
        private String accessKey;
        private String instanceName;

        public String getEndpoint() {
            return endpoint;
        }

        public void setEndpoint(String endpoint) {
            this.endpoint = endpoint;
        }

        public String getAccessId() {
            return accessId;
        }

        public void setAccessId(String accessId) {
            this.accessId = accessId;
        }

        public String getAccessKey() {
            return accessKey;
        }

        public void setAccessKey(String accessKey) {
            this.accessKey = accessKey;
        }

        public String getInstanceName() {
            return instanceName;
        }

        public void setInstanceName(String instanceName) {
            this.instanceName = instanceName;
        }
    }
    static {
        FileInputStream fin = null;
        try {
            fin = new FileInputStream(System.getProperty("user.home") + "/" + "tablestoreConf.json");
            String jsonString = IOUtils.toString(fin);
            Gson gson = new Gson();
            conf = gson.fromJson(jsonString, Conf.class);
            asyncClient = new AsyncClient(conf.getEndpoint(),
                    conf.getAccessId(),
                    conf.getAccessKey(),
                    conf.getInstanceName());
            tunnelClient = new TunnelClient(conf.getEndpoint(),
                    conf.getAccessId(),
                    conf.getAccessKey(),
                    conf.getInstanceName());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fin.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    
    public static AsyncClient getAsyncClient(){
        return asyncClient;
    }

    
    public static void close(){
        if(asyncClient != null) asyncClient.shutdown();
        if(tunnelClient != null){
            tunnelClient.shutdown();
        }
    }

    public static TunnelClient getTunnelClient() {
        return tunnelClient;
    }
}

3.插入数据
    @Test
    public void test04() throws ParseException, IOException {
        String sensor = "270a";
        BufferedReader bufferedReader = new BufferedReader(new FileReader("E:\JavaWorkSpaces\tablestore-study\sn3.txt"));
        String line;
        bufferedReader.readLine(); //去掉首行
        long currentLine = 0;
        while ((line = bufferedReader.readLine()) != null) {
            currentLine++;
            String[] split = line.split("t");
            String sn = split[0];
            String parentSn = split[1];
            List columnList = new ArrayList<>();
            List columns = Arrays.asList(
                    new Column("parent_sn", ColumnValue.fromString(parentSn)),
                    new Column("parent_type", ColumnValue.fromString("采集器")),
                    new Column("status", ColumnValue.fromString("alert")),
                    new Column("update_time", ColumnValue.fromLong(System.currentTimeMillis())),
                    new Column("INV_ST1", ColumnValue.fromString("value1")),
                    new Column("Et_ge0", ColumnValue.fromString("value2")));
            columnList.addAll(columns);
            for (int j = 0; j < 200; j++) {
                columnList.add(new Column("col" + j, ColumnValue.fromString("col" + j)));
            }
            deviceLatestInfo.updateDeviceLatestInfo(sensor, sn, columnList);
            System.out.println("sn:" + sn + "  parent sn:" + parentSn + " line:" + currentLine);
        }
        bufferedReader.close();
    }
 
    public void updateDeviceLatestInfo(String sensor, String sn, List columnList){
        RowUpdateChange rowUpdateChange = new RowUpdateChange(tableName, buildPrimaryKey(sensor, sn));
        rowUpdateChange.put(columnList);
        UpdateRowRequest updateRowRequest = new UpdateRowRequest(rowUpdateChange);
        asyncClient.asSyncClient().updateRow(updateRowRequest);
    }
 
    public PrimaryKey buildPrimaryKey(String sensor, String sn){
        PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryKeyBuilder.addPrimaryKeyColumn("sensor", PrimaryKeyValue.fromString(sensor));
        primaryKeyBuilder.addPrimaryKeyColumn("sn", PrimaryKeyValue.fromString(sn));
        return primaryKeyBuilder.build();
    }

4.获取数据
    public Row getDeviceLatestInfo(String sensor, String sn){
        SingleRowQueryCriteria rowQueryCriteria = new SingleRowQueryCriteria(tableName, buildPrimaryKey(sensor, sn));
        rowQueryCriteria.setMaxVersions(1);
        GetRowRequest getRowRequest = new GetRowRequest(rowQueryCriteria);
        GetRowResponse getRowResponse = asyncClient.asSyncClient().getRow(getRowRequest);
        return getRowResponse.getRow();
    }

5.官方最佳实际

三、Wide Cloum 模型介绍


 上图为官方的图,这个图非常形象的介绍了这个模式的组成。我感觉和hbase的存储模型类似。Hbase 的RowKey 和Primary Keys 相对应,这个模型感觉把Hbase的rowkey拆分成多个的感觉,其他没有什么太大不同。

四、表设计

在大数据的情况下,数据倾斜应该是影响查询等效率的最大原因之一。所以在选择使用分区键时需要考虑让数据尽量的分布均匀。

热点问题:



这个表设计有很明显的热点问题,每次数据写入都是在表的末尾追加数据,而数据是按照分区键的范围进行分区的,也就是每次数据写入都会写入最后一个分区,而无法把写入负载平衡到多台机器上。

解决方案一:

        使用MachineIp作为分区键

解决方案二:

        使用MachineIp作为分区键,把IP做一次MD5拼接,避免某个IP段热点数据问题,如下图:

  • 控制一个分区的数据大小在10GB以内

  • 不要使用递增的分区键
  • 主键长度不宜过长,控制在1K以内,尽可能小提升查询效率
总结

好记性不如烂笔头,下次把索引和通道总结一下。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/328910.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号