【HBase整合Hive】HBase-1.4.8整合Hive-2.3.3过程

HBase-1.4.8整合Hive-2.3.3过程

一、摘要

  1. HBase集成Hive,由Hive来编写SQL语句操作HBase有以下好处

    • 简化操作:Hive提供了类SQL的查询语言HiveQL,对于熟悉SQL的用户来说,无需学习HBase的原生Java API或其他复杂的操作方式,就可以方便地对HBase中的数据进行查询、插入、更新等操作。这大大降低了开发和使用的门槛,提高了数据操作的效率。
    • 支持复杂查询:Hive具有强大的查询处理能力,能够支持复杂的SQL查询,如多表关联、分组、聚合等操作。而HBase本身主要是一个列存储的NoSQL数据库,对于复杂查询的支持相对有限。通过Hive集成,可以利用Hive的查询优化器和执行引擎来处理这些复杂查询,方便用户从HBase中获取更有价值的信息。
    • 数据处理和分析:Hive通常与Hadoop生态系统中的其他组件紧密集成,如HDFS、MapReduce等,这使得它能够方便地进行大规模数据的处理和分析。当Hive与HBase集成后,可以将HBase中的数据与Hadoop生态系统中的其他数据结合起来进行综合分析,充分发挥Hadoop生态系统的优势。
    • 数据抽象和统一管理:Hive为HBase数据提供了一种抽象层,将HBase表映射为Hive表,使得用户可以将HBase数据视为传统的关系型表进行管理和操作。这样可以在一定程度上统一数据的管理和访问方式,方便用户在不同的应用场景中使用HBase数据。
    • 支持数据仓库功能:Hive最初是为数据仓库应用而设计的,它支持数据的ETL(提取、转换、加载)操作、数据分区、数据存储格式管理等功能。通过集成HBase,可以将HBase作为数据仓库的底层存储之一,利用Hive的数据仓库功能来管理和维护HBase中的数据,实现更高效的数据管理和分析。
  2. HBase集成Hive,由Hive编写SQL语句操作HBase也存在一些弊端,主要体现在以下几个方面:

    • 性能损耗
      • Hive在执行SQL语句时,通常会将其转换为MapReduce任务或其他计算框架的任务来执行,这中间涉及到复杂的解析、优化和任务调度过程,会带来一定的性能开销。而HBase本身具有高效的实时读写能力,集成Hive后,可能无法充分发挥HBase的实时性优势,对于一些对实时性要求较高的查询,性能可能不如直接使用HBase原生API。
      • Hive的查询优化器主要是针对传统的关系型数据模型和磁盘存储设计的,对于HBase这种列存储、基于内存和分布式文件系统的存储结构,优化效果可能不理想。例如,Hive可能无法很好地利用HBase的列族、数据块缓存等特性来提高查询性能。
    • 功能限制
      • Hive的SQL语法虽然功能强大,但并不能完全覆盖HBase的所有功能。例如,HBase的一些高级特性,如协处理器、分布式计数器等,很难通过Hive SQL来直接使用。如果应用程序需要使用这些特性,就需要在Hive和HBase之间进行切换,增加了开发和维护的复杂性。
      • Hive对HBase数据类型的支持存在一定限制。HBase的数据类型较为灵活,而Hive有自己固定的数据类型体系,在数据集成时可能会出现类型转换问题,导致数据精度丢失或查询结果不准确。
    • 架构复杂性
      • 集成Hive和HBase增加了系统架构的复杂性。需要同时维护Hive和HBase两个系统的正常运行,包括它们各自的配置、版本兼容性、集群资源管理等。任何一个组件出现问题,都可能影响到整个系统的正常运行,增加了运维的难度和成本。
      • 在数据处理流程中,数据可能需要在Hive和HBase之间进行多次转换和传输,这不仅增加了数据处理的时间和网络开销,还可能导致数据一致性问题。如果在集成过程中没有合理设计数据同步和一致性维护机制,可能会出现数据不一致的情况,影响数据分析的准确性。
  3. 尽管HBase集成Hive存在一些弊端,但两者进行集成仍然具有重要意义,主要原因如下:

    • 技术互补
      • HBase擅长处理大规模的实时数据存储和随机读写,能够在海量数据中快速定位和查询数据,适用于对实时性要求高的场景,如实时监控、金融交易等。而Hive在处理复杂的SQL查询、数据仓库管理和批处理分析方面具有优势,能够方便地进行数据汇总、统计分析和报表生成。通过集成,可将HBase的实时数据处理能力与Hive的数据分析能力相结合,满足不同业务场景下的需求。
      • Hive可以将结构化的数据以表的形式进行管理,提供了一种类似于关系型数据库的操作方式,方便用户进行数据定义、查询和管理。HBase则以其灵活的列存储结构和分布式架构,能够存储半结构化或非结构化数据。两者集成后,可以在Hive中对HBase中的半结构化或非结构化数据进行处理和分析,拓展了数据处理的范围。
    • 保护投资和技术栈整合
      • 许多企业已经在Hadoop生态系统上进行了大量投资,Hive是Hadoop生态中常用的数据仓库工具,而HBase作为高性能的分布式数据库也被广泛应用。集成两者可以充分利用企业现有的技术栈和基础设施,避免重复建设和资源浪费,保护企业在大数据领域的前期投资。
      • 对于已经熟悉Hive SQL的开发人员和数据分析师来说,通过集成HBase和Hive,他们可以在不学习新的复杂API的情况下,利用现有的技能和知识来处理HBase中的数据,降低了学习成本和开发难度,提高了工作效率。
    • 支持多样化的业务需求
      • 在实际业务中,往往既需要对实时数据进行快速查询和处理,又需要对历史数据进行复杂的分析和挖掘。HBase集成Hive可以同时满足这两类需求,为企业提供更全面的数据处理和分析解决方案。例如,在电商领域,HBase可以用于实时记录用户的行为数据,如点击、购买等,而Hive可以对这些数据进行分析,挖掘用户的消费习惯、购买趋势等,为企业的营销策略提供支持。
      • 随着业务的发展,数据量和数据类型不断增加,对数据处理的要求也越来越多样化。集成HBase和Hive可以更好地应对这些变化,提供更灵活的数据处理和分析能力,帮助企业更好地利用数据资产,提升竞争力。

二、整合过程

HBase1.4.8和Hive-2.3.3各种的安装步骤请参考基于OpenEuler国产操作系统大数据实验环境搭建。两者集成的步骤如下:

  1. 修改hive-site.xml
    添加zookeeper的连接配置项:

    xml 复制代码
      <!-- 与HBase集成 -->
      <!-- 指定zookeeper集群地址 -->
      <property>
        <name>hive.zookeeper.quorum</name>
        <value>s1,s2,s3</value>
      </property>
    
      <property>
        <name>hive.zookeeper.client.port</name>
        <value>2181</value>
      </property>
  2. 将hbase-site.xml复制到$HIVE_HOME/conf/目录

    shell 复制代码
    cp $HBASE_HOME/conf/hbase-site.xml $HIVE_HOME/conf/
  3. 验证

    • 确保zookeeper和hbase处于启动状态

    • 执行hive 命令,进程hive的CLI界面中

      shell 复制代码
      [root@s1 hive]# hive
      ......
      Logging initialized using configuration in jar:file:/mysoft/hive/lib/hive-common-2.3.3.jar!/hive-log4j2.properties Async: true
      Hive-on-MR is deprecated in Hive 2 and may not be available in the future versions. Consider using a different execution engine 1.X releases.
      hive>
    • 在hive的CLI中创建一张表:

      sql 复制代码
      create table hive_to_hbase_emp_table(
      empno int,
      ename string,
      job string,
      mgr int,
      hiredate string,
      sal double,
      comm double,
      deptno int)
      stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' with serdeproperties ("hbase.columns.mapping"=":key,info:ename,info:job,info:mgr,info:hiredate,info:sal,info:comm,info:deptno") tblproperties("hbase.table.name"="hive_to_hbase_emp_table");

      执行上述SQL,结果如下:

      sql 复制代码
      hive> create table hive_to_hbase_emp_table(
          > empno int,
          > ename string,
          > job string,
          > mgr int,
          > hiredate string,
          > sal double,
          > comm double,
          > deptno int)
          > stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' with serdeproperties ("hbase.columns.mapping"=":key,info:ename,info:job,info:mgr,info:hiredate,info:sal,info:comm,info:deptno") tblproperties("hbase.table.name"="hive_to_hbase_emp_table");
      OK
      Time taken: 4.958 seconds
      hive>

      说明Hive与HBase集成已经正常。

    • 在hbase shell中查看是否由hive创建的表:

      shell 复制代码
      hbase(main):001:0> list
      TABLE
      hive_to_hbase_emp_table
      1 row(s) in 0.8890 seconds
      => ["hive_to_hbase_emp_table"]
      hbase(main):002:0>
    • 在hive的cli中,创建一张hive的内部表hive_inner_emp,用于将本地文件的数据加载到该表,为后面往hbase中的表做准备(这里仅仅学习和测试演示使用):

      sql 复制代码
      create table hive_inner_emp(
      empno int,
      ename string,
      job string,
      mgr int,
      hiredate string,
      sal double,
      comm double,
      deptno int)
      row format delimited fields terminated by ',';

      执行上述SQL完成hive_inner_emp表创建。
      然后加载将本地的emp.csv文件的数据到该表中:

      shell 复制代码
      load data local inpath '/tools/emp.csv' into table hive_inner_emp;

      命令执行正常时,数据已经添加到hive_inner_emp表中:

      sql 复制代码
      hive> select * from hive_inner_emp;
      OK
      7369    SMITH   CLERK   7902    1980/12/17      800.0   NULL    20
      7499    ALLEN   SALESMAN        7698    1981/2/20       1600.0  300.0   30
      7521    WARD    SALESMAN        7698    1981/2/22       1250.0  500.0   30
      7566    JONES   MANAGER 7839    1981/4/2        2975.0  NULL    20
      7654    MARTIN  SALESMAN        7698    1981/9/28       1250.0  1400.0  30
      7698    BLAKE   MANAGER 7839    1981/5/1        2850.0  NULL    30
      7782    CLARK   MANAGER 7839    1981/6/9        2450.0  NULL    10
      7788    SCOTT   ANALYST 7566    1987/4/19       3000.0  NULL    20
      7839    KING    PRESIDENT       NULL    1981/11/17      5000.0  NULL    10
      7844    TURNER  SALESMAN        7698    1981/9/8        1500.0  0.0     30
      7876    ADAMS   CLERK   7788    1987/5/23       1100.0  NULL    20
      7900    JAMES   CLERK   7698    1981/12/3       9500.0  NULL    30
      7902    FORD    ANALYST 7566    1981/12/3       3000.0  NULL    20
      7934    MILLER  CLERK   7782    1982/1/23       1300.0  NULL    10
      Time taken: 0.668 seconds, Fetched: 14 row(s)
    • hive_inner_emp表数据插入到hive_to_hbase_emp_table表中:

      sql 复制代码
      insert into hive_to_hbase_emp_table select * from hive_inner_emp;

      正常执行结果如下所示:

      shell 复制代码
      hive> insert into hive_to_hbase_emp_table select * from hive_inner_emp;
      WARNING: Hive-on-MR is deprecated in Hive 2 and may not be available in the future versions. Consider using a different execution engine (i.e. spark, tez) or using Hive 1.X releases.
      Query ID = root_20250513134124_d0a93e1f-e852-405e-ad52-2ddaae763d9f
      Total jobs = 1
      Launching Job 1 out of 1
      Number of reduce tasks is set to 0 since there's no reduce operator
      Starting Job = job_1747100297537_0014, Tracking URL = http://s1:8088/proxy/application_1747100297537_0014/
      Kill Command = /mysoft/hadoop/bin/hadoop job  -kill job_1747100297537_0014
      Hadoop job information for Stage-3: number of mappers: 1; number of reducers: 0
      2025-05-13 13:41:56,018 Stage-3 map = 0%,  reduce = 0%
      2025-05-13 13:42:17,910 Stage-3 map = 100%,  reduce = 0%, Cumulative CPU 4.98 sec
      MapReduce Total cumulative CPU time: 4 seconds 980 msec
      Ended Job = job_1747100297537_0014
      MapReduce Jobs Launched:
      Stage-Stage-3: Map: 1   Cumulative CPU: 4.98 sec   HDFS Read: 5951 HDFS Write: 0 SUCCESS
      Total MapReduce CPU Time Spent: 4 seconds 980 msec
      OK
      Time taken: 55.57 seconds
      hive>
    • 在hbase shell中执行scan命令查看该表数据:

      sql 复制代码
      hbase(main):002:0> scan 'hive_to_hbase_emp_table'
      ROW                              COLUMN+CELL
       7369                            column=info:deptno, timestamp=1747114968171, value=20
       7369                            column=info:ename, timestamp=1747114968171, value=SMITH
       7369                            column=info:hiredate, timestamp=1747114968171, value=1980/12/17
       7369                            column=info:job, timestamp=1747114968171, value=CLERK
       7369                            column=info:mgr, timestamp=1747114968171, value=7902
       7369                            column=info:sal, timestamp=1747114968171, value=800.0
       7499                            column=info:comm, timestamp=1747114968171, value=300.0
       7499                            column=info:deptno, timestamp=1747114968171, value=30
       7499                            column=info:ename, timestamp=1747114968171, value=ALLEN
       7499                            column=info:hiredate, timestamp=1747114968171, value=1981/2/20
       7499                            column=info:job, timestamp=1747114968171, value=SALESMAN
       7499                            column=info:mgr, timestamp=1747114968171, value=7698
       7499                            column=info:sal, timestamp=1747114968171, value=1600.0
       7521                            column=info:comm, timestamp=1747114968171, value=500.0
       7521                            column=info:deptno, timestamp=1747114968171, value=30
       7521                            column=info:ename, timestamp=1747114968171, value=WARD
       7521                            column=info:hiredate, timestamp=1747114968171, value=1981/2/22
       7521                            column=info:job, timestamp=1747114968171, value=SALESMAN
       7521                            column=info:mgr, timestamp=1747114968171, value=7698
       7521                            column=info:sal, timestamp=1747114968171, value=1250.0
       7566                            column=info:deptno, timestamp=1747114968171, value=20
       7566                            column=info:ename, timestamp=1747114968171, value=JONES
       7566                            column=info:hiredate, timestamp=1747114968171, value=1981/4/2
       7566                            column=info:job, timestamp=1747114968171, value=MANAGER
       7566                            column=info:mgr, timestamp=1747114968171, value=7839
       7566                            column=info:sal, timestamp=1747114968171, value=2975.0
       7654                            column=info:comm, timestamp=1747114968171, value=1400.0
       7654                            column=info:deptno, timestamp=1747114968171, value=30
       7654                            column=info:ename, timestamp=1747114968171, value=MARTIN
       7654                            column=info:hiredate, timestamp=1747114968171, value=1981/9/28
       7654                            column=info:job, timestamp=1747114968171, value=SALESMAN
       7654                            column=info:mgr, timestamp=1747114968171, value=7698
       7654                            column=info:sal, timestamp=1747114968171, value=1250.0
       7698                            column=info:deptno, timestamp=1747114968171, value=30
       7698                            column=info:ename, timestamp=1747114968171, value=BLAKE
       7698                            column=info:hiredate, timestamp=1747114968171, value=1981/5/1
       7698                            column=info:job, timestamp=1747114968171, value=MANAGER
       7698                            column=info:mgr, timestamp=1747114968171, value=7839
       7698                            column=info:sal, timestamp=1747114968171, value=2850.0
       7782                            column=info:deptno, timestamp=1747114968171, value=10
       7782                            column=info:ename, timestamp=1747114968171, value=CLARK
       7782                            column=info:hiredate, timestamp=1747114968171, value=1981/6/9
       7782                            column=info:job, timestamp=1747114968171, value=MANAGER
       7782                            column=info:mgr, timestamp=1747114968171, value=7839
       7782                            column=info:sal, timestamp=1747114968171, value=2450.0
       7788                            column=info:deptno, timestamp=1747114968171, value=20
       7788                            column=info:ename, timestamp=1747114968171, value=SCOTT
       7788                            column=info:hiredate, timestamp=1747114968171, value=1987/4/19
       7788                            column=info:job, timestamp=1747114968171, value=ANALYST
       7788                            column=info:mgr, timestamp=1747114968171, value=7566
       7788                            column=info:sal, timestamp=1747114968171, value=3000.0
       7839                            column=info:deptno, timestamp=1747114968171, value=10
       7839                            column=info:ename, timestamp=1747114968171, value=KING
       7839                            column=info:hiredate, timestamp=1747114968171, value=1981/11/17
       7839                            column=info:job, timestamp=1747114968171, value=PRESIDENT
       7839                            column=info:sal, timestamp=1747114968171, value=5000.0
       7844                            column=info:comm, timestamp=1747114968171, value=0.0
       7844                            column=info:deptno, timestamp=1747114968171, value=30
       7844                            column=info:ename, timestamp=1747114968171, value=TURNER
       7844                            column=info:hiredate, timestamp=1747114968171, value=1981/9/8
       7844                            column=info:job, timestamp=1747114968171, value=SALESMAN
       7844                            column=info:mgr, timestamp=1747114968171, value=7698
       7844                            column=info:sal, timestamp=1747114968171, value=1500.0
       7876                            column=info:deptno, timestamp=1747114968171, value=20
       7876                            column=info:ename, timestamp=1747114968171, value=ADAMS
       7876                            column=info:hiredate, timestamp=1747114968171, value=1987/5/23
       7876                            column=info:job, timestamp=1747114968171, value=CLERK
       7876                            column=info:mgr, timestamp=1747114968171, value=7788
       7876                            column=info:sal, timestamp=1747114968171, value=1100.0
       7900                            column=info:deptno, timestamp=1747114968171, value=30
       7900                            column=info:ename, timestamp=1747114968171, value=JAMES
       7900                            column=info:hiredate, timestamp=1747114968171, value=1981/12/3
       7900                            column=info:job, timestamp=1747114968171, value=CLERK
       7900                            column=info:mgr, timestamp=1747114968171, value=7698
       7900                            column=info:sal, timestamp=1747114968171, value=9500.0
       7902                            column=info:deptno, timestamp=1747114968171, value=20
       7902                            column=info:ename, timestamp=1747114968171, value=FORD
       7902                            column=info:hiredate, timestamp=1747114968171, value=1981/12/3
       7902                            column=info:job, timestamp=1747114968171, value=ANALYST
       7902                            column=info:mgr, timestamp=1747114968171, value=7566
       7902                            column=info:sal, timestamp=1747114968171, value=3000.0
       7934                            column=info:deptno, timestamp=1747114968171, value=10
       7934                            column=info:ename, timestamp=1747114968171, value=MILLER
       7934                            column=info:hiredate, timestamp=1747114968171, value=1982/1/23
       7934                            column=info:job, timestamp=1747114968171, value=CLERK
       7934                            column=info:mgr, timestamp=1747114968171, value=7782
       7934                            column=info:sal, timestamp=1747114968171, value=1300.0
      14 row(s) in 0.9040 seconds
      
      hbase(main):003:0>
    • 在hive的cli中向hive_to_hbase_emp_table表中写入一条数据,验证是否正常写入:

      sql 复制代码
      hive> INSERT INTO TABLE hive_to_hbase_emp_table VALUES (7935, 'Alice', 'Engineer', null, '2023-01-01', 10000.0, null, 10);
      WARNING: Hive-on-MR is deprecated in Hive 2 and may not be available in the future versions. Consider using a different execution engine (i.e. spark, tez) or using Hive 1.X releases.
      Query ID = root_20250513134721_628fd4af-a8f7-4c6e-b9c1-9e8f22e78c03
      Total jobs = 1
      Launching Job 1 out of 1
      Number of reduce tasks is set to 0 since there's no reduce operator
      Starting Job = job_1747100297537_0015, Tracking URL = http://s1:8088/proxy/application_1747100297537_0015/
      Kill Command = /mysoft/hadoop/bin/hadoop job  -kill job_1747100297537_0015
      Hadoop job information for Stage-3: number of mappers: 1; number of reducers: 0
      2025-05-13 13:47:49,256 Stage-3 map = 0%,  reduce = 0%
      2025-05-13 13:48:06,096 Stage-3 map = 100%,  reduce = 0%, Cumulative CPU 6.2 sec
      MapReduce Total cumulative CPU time: 6 seconds 200 msec
      Ended Job = job_1747100297537_0015
      MapReduce Jobs Launched:
      Stage-Stage-3: Map: 1   Cumulative CPU: 6.2 sec   HDFS Read: 6082 HDFS Write: 0 SUCCESS
      Total MapReduce CPU Time Spent: 6 seconds 200 msec
      OK
      Time taken: 47.183 seconds
      hive>
    • 在hbase shell中执行get命令查看该条数据:

      sql 复制代码
      hbase(main):006:0> get 'hive_to_hbase_emp_table','7935'
      COLUMN                           CELL
       info:deptno                     timestamp=1747115316165, value=10
       info:ename                      timestamp=1747115316165, value=Alice
       info:hiredate                   timestamp=1747115316165, value=2023-01-01
       info:job                        timestamp=1747115316165, value=Engineer
       info:sal                        timestamp=1747115316165, value=10000.0
      5 row(s) in 0.1260 seconds

      到此,说明Hive-2.3.3和HBase-1.4.8集成完毕。

三、注意事项

  1. Hive和HBase的版本务必兼容,请查看官网获取HBase和Hive的兼容版本。否则,会有各种意想不到的错误产生。

  2. 在hive创建的hive_to_hbase_emp_table表,hive只保存该表的元信息,该表所在hdfs上的路径为:

    shell 复制代码
    drwxr-xr-x   - root supergroup          0 2025-05-13 15:47 /user/hive/warehouse/hive_to_hbase_emp_table

    真实数据是存储在hbase路径下:

    shell 复制代码
    [root@s1 conf]# hdfs dfs -ls -R /hbase/data/default/hive_to_hbase_emp_table
    drwxr-xr-x   - root supergroup          0 2025-05-13 15:26 /hbase/data/default/hive_to_hbase_emp_table/.tabledesc
    -rw-r--r--   3 root supergroup        303 2025-05-13 15:26 /hbase/data/default/hive_to_hbase_emp_table/.tabledesc/.tableinfo.0000000001
    drwxr-xr-x   - root supergroup          0 2025-05-13 15:26 /hbase/data/default/hive_to_hbase_emp_table/.tmp
    drwxr-xr-x   - root supergroup          0 2025-05-13 15:26 /hbase/data/default/hive_to_hbase_emp_table/14a4000780edafd6a8b46b52f046f863
    -rw-r--r--   3 root supergroup         58 2025-05-13 15:26 /hbase/data/default/hive_to_hbase_emp_table/14a4000780edafd6a8b46b52f046f863/.regioninfo
    drwxr-xr-x   - root supergroup          0 2025-05-13 15:26 /hbase/data/default/hive_to_hbase_emp_table/14a4000780edafd6a8b46b52f046f863/info
    drwxr-xr-x   - root supergroup          0 2025-05-13 15:26 /hbase/data/default/hive_to_hbase_emp_table/14a4000780edafd6a8b46b52f046f863/recovered.edits
    -rw-r--r--   3 root supergroup          0 2025-05-13 15:26 /hbase/data/default/hive_to_hbase_emp_table/14a4000780edafd6a8b46b52f046f863/recovered.edits/2.seqid
    [root@s1 conf]#
相关推荐
小陈工1 小时前
Python Web开发入门(十七):Vue.js与Python后端集成——让前后端真正“握手言和“
开发语言·前端·javascript·数据库·vue.js·人工智能·python
科技小花5 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸5 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain5 小时前
linux个人心得22 (mysql)
数据库·mysql
阿里小阿希6 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神6 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员6 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
不吃香菜学java6 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
一个天蝎座 白勺 程序猿7 小时前
Apache IoTDB(15):IoTDB查询写回(INTO子句)深度解析——从语法到实战的ETL全链路指南
数据库·apache·etl·iotdb
不知名的老吴7 小时前
Redis的延迟瓶颈:TCP栈开销无法避免
数据库·redis·缓存