Phoenix 指南-01

Phoenix 指南-01

create 'jinshan' ,'info','info1'

put 'jinshan','1001','info:createtime',Bytes.toBytes(1602237645881)
put 'jinshan','1001','info1:age',Bytes.toBytes(16)


create view "jinshan" (id varchar primary key,"info"."createtime" UNSIGNED_DATE,"info1"."age" UNSIGNED_LONG)column_encoded_bytes=0;

 select * from "jinshan";

create table "t2_hbase" (id varchar primary key,"mycg"."age" UNSIGNED_INT,"mycg"."datestr" UNSIGNED_DATE,"mycg"."name" varchar)column_encoded_bytes=0;
select * from "t2_hbase";


create table user (
"session_id" varchar(100) not null primary key,
"f"."cookie_id" varchar(100),
"f"."visit_time" varchar(100),
"f"."user_id" varchar(100),
"f"."age" Integer,
"f"."sex" varchar(100),
"f"."visit_url" varchar(100),
"f"."visit_os" varchar(100),
"f"."browser_name" varchar(100),
"f"."visit_ip" varchar(100),
"f"."province" varchar(100),
"f"."city" varchar(100),
"f"."page_id" varchar(100),
"f"."goods_id" varchar(100),
"f"."shop_id" varchar(100)) column_encoded_bytes=0;


phoenix-psql -t USER localhost:2181 /data/leo_jie/user.csv
备注:因为我安装的是 CDH 版的 Phoenix,所以命令会和原文略有不同。这种方式导入数据的效率挺慢的,数据量大的话还是推荐使用之前提到的 bulkload CSV 文件的方式。500 万的测试数据大概三个 G,导入耗时 15 分钟左右。

create index USER_COOKIE_ID_INDEX on USER ("f"."cookie_id");
create local index USER_USER_ID_INDEX on USER ("f"."user_id");
drop index USER_USER_ID_INDEX on "USER";
create local index USER_USER_ID_INDEX on USER ("f"."user_id") async;


hbase org.apache.phoenix.mapreduce.index.IndexTool --data-table USER --index-table USER_USER_ID_INDEX --output-path USER_USER_ID_INDEX
${HBASE_HOME}/bin/hbase org.apache.phoenix.mapreduce.index.IndexTool
  --schema MY_SCHEMA --data-table MY_TABLE --index-table ASYNC_IDX
  --output-path ASYNC_IDX_HFILES

create index USER_COOKIE_ID_AGE_INDEX on USER ("f"."cookie_id") include("f"."age");

第三种方式是在查询的时候提示其使用索引。 在 select 和 column_name 之间加上/+ Index(<表名> <index 名>)/,通过这种方式强制使用索引。
select /*+ index(user,USER_COOKIE_ID_AGE_INDEX) */ "age" from user where "cookie_id"='b80da72c-c6e4-4c79-9fc5-08e7253f6596';
select /*+ index(user, USER_COOKIE_ID_AGE_INDEX) */"age","sex" from user where "cookie_id"='b80da72c-c6e4-4c79-9fc5-08e7253f6596';

select /*+ index(user USER_COOKIE_ID_AGE_INDEX) */"age", "sex" from user where "cookie_id"='b80da72c-c6e4-4c79-9fc5-08e7253f6596';
explain select /*+ index(user USER_COOKIE_ID_AGE_INDEX) */"age", "sex" from user where "cookie_id"='b80da72c-c6e4-4c79-9fc5-08e7253f6596';

1 alter index USER_PHONE_INDEX  on person.USER rebuild;
2 alter index USER_PHONE_INDEX  on person.USER rebuild async;
如果你的 Phoenix 表数据量很大,还是老老实实使用语句 2 来进行异步索引重建吧。异步索引重建之后,索引的状态被置为了 BUILDING,此时,还需要运行 IndexTool 命令来加载索引数据。

hbase org.apache.phoenix.mapreduce.index.IndexTool \
--schema PERSON --data-table USER --index-table USER_PHONE_INDEX \
--output-path USER_PHONE_INDEX
这里说起索引表的状态,不得不提一下索引表的生命周期。我们以异步的方式初次创建或者二次创建的索引表的状态是 BUILDING,即构建状态,此时索引表还不能正常使用,当我们运行完 IndexTool 这个索引表构建工具之后,索引表的状态被修改为 ACTIVE,意味激活状态。此时索引表就可以正常使用了,这里就涉及到了索引表的生命周期。有关生命周期更详细的介绍,还请移步至 Phoenix 的官方文档,或者参考此篇博客https://www.cnblogs.com/hbase-community/p/8879848.html

























hbase-site.xml 配置

hbase-site.xml

1. index.builder.threads.max
创建索引时,使用的最大线程数。
默认值: 10。

2. index.builder.threads.keepalivetime
创建索引的创建线程池中线程的存活时间,单位:秒。
默认值: 60

3. index.writer.threads.max
写索引表数据的写线程池的最大线程数。
更新索引表可以用的最大线程数,也就是同时可以更新多少张索引表,数量最好和索引表的数量一致。
默认值: 10

4. index.writer.threads.keepalivetime
索引写线程池中,线程的存活时间,单位:秒。
默认值:60

5. hbase.htable.threads.max
每一张索引表可用于写的线程数。
默认值: 2,147,483,647

6. hbase.htable.threads.keepalivetime
索引表线程池中线程的存活时间,单位:秒。
默认值: 60

7. index.tablefactory.cache.size
允许缓存的索引表的数量。
增加此值,可以在写索引表时不用每次都去重复的创建htable,这个值越大,内存消耗越多。
默认值: 10

8. org.apache.phoenix.regionserver.index.handler.count
处理全局索引写请求时,可以使用的线程数。
默认值: 30

模拟测试数据的脚本

#!/usr/bin/env python
# -*- coding:utf-8 -*-

"""
:Description: 模拟用户数据
:Owner: cw
:Create time: 2023年8月31日15:02:05
"""

import uuid
import time
import random
import struct
import socket


def generate_random_time():
    a1 = (2018, 1, 1, 0, 0, 0, 0, 0, 0)  # 设置开始日期时间元组(1976-01-01 00:00:00)
    a2 = (2019, 12, 31, 23, 59, 59, 0, 0, 0)  # 设置结束日期时间元组(1990-12-31 23:59:59)
    start = time.mktime(a1)  # 生成开始时间戳
    end = time.mktime(a2)  # 生成结束时间戳
    # 随机生成10个日期字符串
    t = random.randint(start, end)  # 在开始和结束时间戳中随机取出一个
    date_tuple = time.localtime(t)  # 将时间戳生成时间元组
    random_date = time.strftime("%Y-%m-%d %H:%M:%S", date_tuple)  # 将时间元组转成格式化字符串
    return random_date


def generate_random_user_id(length=9):
    user_id = str(random.randint(1, 999999999))
    if len(user_id) < length:
        append_length = length - len(user_id)
        user_id = '0' * append_length + user_id
    return user_id


def random_str():
    data = "1234567890zxcvbnmlkjhgfdsaqwertyuiop"
    # 用时间来做随机播种
    random.seed(time.time())
    # 随机选取数据
    sa = []
    for i in range(20):
        sa.append(random.choice(data))
    salt = "gp_" + ''.join(sa)
    return salt


def generate_random_url():
    channels = [
        "BTV2", "BTV3", "BTV4", "BTV5", "BTV6", "BTV7", "BTV8", "BTV9",
        "BTVWorld", "CCTV12", "CCTV2", "CCTV3", "CCTV5", "CCTV6", "CCTV6World", "CCTV7",
        "CCTV8", "CCTV9World", "CCTVA", "CCTVChild", "CCTVE", "CCTVEN", "CCTVF", "CCTVFYYY",
        "CCTVHJJC", "CCTVMusic", "CCTVNEWS", "CCTVR", "CETV1", "CETV3", "ChongQingTV", "ChongQingWorld",
        "GZChild", "GZEnglish", "GZFinance", "GZJingSai", "GZMovie", "GanSuTV", "GuangXiTV", "GuiZhouTV",
    ]

    host = '10.160.1.21'
    date = '2014/10/31'
    bitrates = ['800000']
    channel = random.choice(channels)
    bitrate = random.choice(bitrates)
    ts_url = ''.join(
        ['http://', host, '/', 'online01/stream/', bitrate, '/', channel, '/', date, '/', random_str()])
    return ts_url

def generate_random_ip():
    RANDOM_IP_POOL = ['192.168.10.222/0']
    str_ip = RANDOM_IP_POOL[random.randint(0, len(RANDOM_IP_POOL) - 1)]
    str_ip_addr = str_ip.split('/')[0]
    str_ip_mask = str_ip.split('/')[1]
    ip_addr = struct.unpack('>I', socket.inet_aton(str_ip_addr))[0]
    mask = 0x0
    for i in range(31, 31 - int(str_ip_mask), -1):
        mask = mask | (1 << i)
    ip_addr_min = ip_addr & (mask & 0xffffffff)
    ip_addr_max = ip_addr | (~mask & 0xffffffff)
    return socket.inet_ntoa(struct.pack('>I', random.randint(ip_addr_min, ip_addr_max)))

def generate_random_province():
    provinces = ['河北省', '山西省', '辽宁省', '吉林省', '黑龙江省', '江苏省', '浙江省', '安徽省', '福建省',
                 '江西省', '山东省', '河南省', '湖北省', '湖南省', '广东省', '海南省', '四川省', '贵州省',
                 '云南省', '陕西省', '甘肃省', '青海省', '台湾省', '上海市', '北京市', '天津市', '重庆市',
                 '香港', '澳门']
    return provinces[random.randint(0, len(provinces) - 1)]


def generate_shop_id():
    shop_no = ['A', 'B', 'C', 'D', 'F', 'F', 'G']
    return shop_no[random.randint(0, len(shop_no) - 1)] + str(random.randint(1, 9999))


def mock_user_data():
    session_id = uuid.uuid4()
    cookie_id = uuid.uuid4()
    visit_time = generate_random_time()
    user_id = generate_random_user_id()
    age = str(random.randint(10, 80))
    sex = 'F' if random.randint(0, 1) == 1 else 'M'
    visit_url = generate_random_url()
    visit_os = 'Windows OS' if random.randint(0, 1) == 1 else 'Mac OS'
    browser_name = 'Google' if random.randint(0, 1) == 1 else 'IE'
    visit_ip = generate_random_ip()
    province = generate_random_province()
    city = province
    page_id = str(random.randint(1, 99999))
    goods_id = str(random.randint(1, 999999999))
    shop_id = generate_shop_id()
    return "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s" \
           % (session_id, cookie_id, visit_time, user_id, age, sex, visit_url,
              visit_os, browser_name, visit_ip, province, city,
              page_id, goods_id, shop_id)


def create_data(rows=5000000):
    for i in range(rows):
        with open('user.csv', 'a')as f:
            f.write(mock_user_data() + "\n")


create_data()

Phoenix 导出csv文件

https://dandelioncloud.cn/article/details/1561504709800587266
https://blog.csdn.net/u012581453/article/details/132428992

source bigdata_env   -- 环境认证
kinit -kt admin.keytab admin   -- 用户认证

-- 设置客户端宽度 
!set maxwidth 3000 

-- 让结果竖着显示 
!set outputformat vertical 
!set outputformat table 

-- 设置数据导出格式 
!outputformat csv 
-- 设置导出数据的存储位置 
!record /home/test/result.csv 
-- 查询数据
select * from test; 
-- 结束导出 
!record 

!tables 



image
使用python连接phoenix的几种方式

https://www.cnblogs.com/java-meng/p/15189311.html

posted @ 2023-08-31 13:44  三里清风18  阅读(54)  评论(0)    收藏  举报