对HANA的认识与相关测试案例

http://scn.sap.com/docs/DOC-35523/  HANA视频学习网站

http://www.erp100.com/article-8632-1.html  对RDBMS、内存数据库(SAP HANA)与 HADOOP 的认识


(High-Performance Analytic Appliance ,简称HANA,高性能分析设备

HANA是一个软硬件结合体,提供高性能的数据查询功能,用户可以直接对大量实时业务数据进行查询和分析,而不需要对业务数据进行建模、聚合等。SAP内存数据库的数据并不是只在内存里,也会不停写到硬盘里,这就用到复制服务器Replication Server,包括Log-based,Trigger-based和ETL-based。这些复制服务器需要用到Sybase Replication Server、Sybase Replication Server Agent、Sybase Adaptive Server EntERPrise (AES,适用性服务器)等,以及HANA Load Controller和BO Data Services。

2010年SAP全球技术研发者大会上,SAP发布了SAP 高性能分析应用软件(SAP High-Performance Analytic Appliance ,简称SAP HANA),2011年则开始将成熟的产品和解决方案向全球推广,目前SAP HANA也是SAP历史上用户增长速度最为迅猛的产品之一。它借助主存储器、处理器技术和应用诀窍领域的最新成果,SAP HANA充分发挥内存数据处理的威力,使分析应用软件获得了前所未有的效能,并由此开启了一个全新的应用软件类别。
SAP HANA是集结了SAP与IBM、 惠普思科富士通、英特尔等硬件商一起合作的结晶,优化的软硬件合成产品将基于内存的计算植入到了业务应用的核心。
软件方面,HANA的内存数据库(SAP In-Memory Database, IMDB)是其重要组成部分,包括数据库服务器(In-Memory Database Server)、建模工具(Studio)和客户端工具(ODBO、JDBC、ODBC、SQLDBC等)。HANA的计算引擎(Computing Engine)是其核心,负责解析并处理对大量数据的各类CRUDQ操作,支持SQL和MDX语句、SAP和non-SAP数据。比较显而易见的一点是,HANA计算引擎要快速处理用户复杂的查询请求,快速返回查询结果。
SAP内存数据库的数据并不是只在内存里,也会不停写到硬盘里,这就用到复制服务器Replication Server,包括Log-based,Trigger-based和ETL-based。这些复制服务器需要用到Sybase Replication Server、Sybase Replication Server Agent、Sybase Adaptive Server EntERPrise (AES,适用性服务器)等,以及HANA Load Controller和BO Data Services。
硬件方面,SAP和多个硬件厂商合作生产支持HANA的高性能服务器,包括Dell R910、Fujitsu、HP DL580、IBM x3850等,以及和Cisco(Cisco Unified Computing System. UCS)等公司的合作。直观地说,这些机器的硬盘可能是数个600GB、转速10k rpm的硬盘组成RAID,内存可能有1T,文件系统可能是ext3或GPFS(IBM通用串行文件系统,General Parallel File System)。
HANA的快在于用大内存提供内存数据库,并在内存数据库里采用列式存储从而可以将更多的数据装进内存(列式存储更适合数据压缩)。
SAP HANA的诞生,主要是应对当前企业里不同来源的海量数据,并将这些不同结构的数据进行整合,进一步实时进行数据挖掘和分析。


从较高层面来看,若要了解 Hadoop,需重点掌握其四大功能:Hadoop是分布式文件系统

  • 商用服务器集群
Hadoop 可以在成百上千台商业(低成本)服务器上运行。套用 Hadoop 的术语来讲,大部分商用服务器都是一个“数据节点(DataNode)”。每个数据节点均只包含一部分数据。具体而言,Hadoop 能够将一个处理作业分解成成百上千个小作业,然后由每台服务器并行执行这些小作业,共同完成数据处理的流程。
  • Hadoop MapReduce 编程模型
  • Hadoop 软件架构
  • Hadoop 生态系统

RDBMS、内存数据库(SAP HANA)与 HADOOP 的区别
挑选在 OLTP 或分析型解决方案环境中使用的数据技术时,我们需要了解各项备选技术之间的差异。下表列出了传统 RDBMS、内存数据库(特别是 SAP HANA)以及 Hadoop 之间的主要区别。该表格并非针对特定产品制作,因而具有一定程度的普遍性。技术发展日新月异,表中列出的详细信息也必然会随之改变。然而,值得注意的是,不同数据库类型所表现出的以下关键差异性,在未来极有可能保持不变:

  • RDBMS 仍将是解决众多问题的可行解决方案,特别是对于时效性要求不高的简单的 OLTP 而言。
  • SAP HANA 等采用内存计算技术的产品,最适用于注重速度(例如,实时数据更新和分析),但数据量不至于过大,并且对于企业而言,成本较为合理的业务场景。
  • Hadoop 则更适用于具备以下特征的场景,即数据数量非常大,数据类型(如非结构化文本)难以采用其他数据库技术进行存储,且对数据分析及其处理速度要求不高,或者必须尽量削减成本。

如何创建XS Job来完成定时任务  

技术连接:http://scn.sap.com/community/chinese/hana/blog
HANA系统的XS引擎提供了定时执行你的任务的功能。你可以让HANA定期地完成一些你指定的操作。

你将在本文中看到如何编写一个简单的XS应用并调度一个XS Job来执行它。这个应用会向特定的表里插入一条记录。

 

1. 前提条件

1.1 这个功能从HANA SPS07开始有效,所以请确保你的HANA是Revision 70之后的版本。

1.2 确保XSEngine正常运行。
在你的Web Browser里输入http://<Web_Server_Host>:80<HANA_instance>/sap/hana/xs/admin/,如果能看到下面的界面就说明XSEngine一切正常。

image1.2-1.png

image1.2-2.png

1.3 HANA上的必要配置
你可以把下面这些和XSengine相关的角色赋给用户(这里我们使用的用户是"DEMO_USER")。
image1.3-1.png

该用户的Schema权限也要赋给用户_SYS_REPO。

image1.3-2.png

在xsengine.ini里添加section "schedule"和参数"enabled"如下。
image1.3-3.png

如果需要向表里写数据,你必须把"sqlscript mode"改成"UNSECURE"(如下图),否则你只能在procedure里使用select语句。
image1.3-4.png

 

2. Procedure

2.1 新建XS project。
image2.1-1.png

image2.1-2.pngimage2.1-3.png

当要给project指定一个workspace时,你可以新建一个workspace或者使用缺省的workspace。
这里我们使用缺省的workspace。

image2.1-4.pngimage2.1-5.png

image2.1-6.pngimage2.1-7.png

你可以在Project Explorer里看到新建的project。

image2.1-8.png

同时你也可以在Web Browser里看到它。

image2.1-9.png

2.2 新建数据库object。
这里我们新建个表来做测试。

image2.2.png

2.3 新建XS JavaScript和XS Job。

按下面的步骤新建XS JavaScript。

image2.3-1.png

image2.3-2.png

.xsjs文件生成之后,如下新建一个JavaScript function。

我们向表DEMO_TABLE里插入一条包含时间戳的记录。

function my_js() {

    var sql = "INSERT INTO DEMO_USER.DEMO_TABLE VALUES ('inserted by javascript job', NOW())";

    var conn = $.db.getConnection();

    var pstmt = conn.prepareStatement(sql);

    pstmt.execute();

    conn.commit();

    conn.close();

}

image2.3-3.png

然后新建一个XS Job。
image2.3-4.png

image2.3-5.pngimage2.3-6.png

.xsjob文件生成之后,可以在XS Job文件里定义任务了。

在"action"里指定刚才新建的XS JavaScript文件里的function。

在"schedules"中指定调度时间,其中的"xscron"同Linux环境的"crontab"的语法类似,这里我们指定每5秒钟执行一次。

{

    "description": "my first JS job",

    "action": "XS_JOB_DEMO:my_js.xsjs::my_js",

    "schedules": [

        {

            "description": "run every 5 seconds",

            "xscron": "* * * * * * 0:59/5"

        }

    ]

}

image2.3-7.png

2.4 新建HANA Procedure和XS job。

按下面的步骤新建XS JavaScript。

image2.4-1.pngimage2.4-2.png

.hdbprocedure文件生成之后,如下新建一个HANA Procedure。

我们也向表DEMO_TABLE里插入一条包含时间戳的记录。

PROCEDURE "DEMO_USER"."XS_JOB_DEMO::my_procedure" ( )

    LANGUAGE SQLSCRIPT

    SQL SECURITY INVOKER

    DEFAULT SCHEMA DEMO_USER

    AS

BEGIN

/*****************************

    Write your procedure logic

*****************************/

    INSERT INTO DEMO_TABLE VALUES('inserted by procedure job', NOW());

END;

image2.4-3.png

然后同样新建一个XS Job来执行这个Procedure。

请注意“action”的语法,和刚才的XS JavaScript是不同的。
这里我们指定每10秒钟执行一次。

{

    "description": "my first Procedure job",

    "action": "XS_JOB_DEMO::my_procedure",

    "schedules": [

        {

            "description": "run every 10 seconds",

            "xscron": "* * * * * * 0:59/10"

        }

    ]

}

image2.4-4.png

2.5 在Web Browser里启动任务。

你可以在HANA XS Administration Tool里看到刚才新建的两个XS Job。

输入"User"和"Locale",勾选"Active",然后 按下"Save"之后XS Job就开始执行了。

你也可以在此监控任务。

image2.5-1.png

image2.5-2.png

从下图可见JavaScript的任务每5秒执行一次,HANA Procedure的任务每10秒执行一次。

image2.5-3.png

   

在之前的调查中,有用户希望可以通过微视频的方法了解SAP HANA。

因此做了一个SAP HANA 权限问题分析的小视频,如果大家觉得内容和形式不错,欢迎点赞。

如果有意见和建议,欢迎留言。

 

视频的主要介绍了两种权限分析的方法:

Authorization Trace

Authorization Dependency Viewer

并分别做了一个简单的例子,如何设置,以及如何分析结果。

 

观看视频点击链接: SAP HANA 权限分析

 

视频中相关的系统视图:

GRANTED_PRIVILEGES

USERS

OBJECTS

 

执行命令:

alter system alter configuration ('indexserver.ini','SYSTEM') SET('trace','authorization')='info' with reconfigure;

alter system alter configuration ('indexserver.ini','SYSTEM') unset ('trace','authorization') with reconfigure;

   

系统迁移HANA 示例及问题诊断

 

1.简介
本blog演示将bw on oracle系统迁移至bw on HANA,并对常见问题作出解答。


2.最佳实践

 

2.1. 导出源系统 (BW on Oracle)
2.1.1 SMIGR_CREATE_DDL (SE38)
这个ABAP程序会针对BW表进行准备工作。
这一步,将会生成用于在目标系统创建表的DDL语句。生成的rowstorelist.txt列出了将会以行存储保存的表。生成的estimated_row_count.txt包含了各个行表的条目信息。这一信息将被用于在导入分布式系统中所使用。
如下note提供了关于这个report的最新信息。请确保在执行SMIGR_CREATE_DD前,将此note中所有提及的关联note安装完毕。
1921023 - SMIGR_CREATE_DDL: Corrections and enhancements for SAP HANA.

您也可以通过如下link获取帮助信息http://scn.sap.com/docs/DOC-47657

1.png

2.png3.png
执行完毕后,你可以找到如下生成的文件

 

4.png

2.1.2 运行SWPM  

在导出系统时,SWPM主要有三个步骤:Export Preparation, Table Splitting Preparation 及 Database Instance Export。建议从service market 下载最新版本的SWPM用于完成系统迁移。


2.1.2.1 Export Preparation

这一步将会创建Export DVD。即生成后续导出系统所用的文件夹目录结构。虽然文件夹目录的创建也可以直接在第三步Export Database Instance时创建,但SWPM在并行执行export/import时会需要您提供Export DVD。

2.1.2.1.1.png2.1.2.1.2.png2.1.2.1.3.png2.1.2.1.4.png2.1.2.1.5.png2.1.2.1.6.png2.1.2.1.7.png

完成后,如下文件夹(空)目录结构将会生成。
2.1.2.1.8.png

2.1.2.2 Table Splitting Preparation
我们使用工具
"SAPuptool"( Fastsplitter)来进行分拆表操作。这一工具是SUM/DMO的一个组成部分。这个工具相对于传统的分拆表工具(R3ta 或Oracle table splitter)能更效率的完成分拆表操作。

你可通过如下link获取SUM:
https://websmp201.sap-ag.de/~form/handler?_APP=00200682500000002672&_EVENT=DISPLAY&_SCENARIO=&_HIER_KEY=501100035870000015092&_HIER_KEY=601100035870000179416&_HIER_KEY=601100035870000236470&_HIER_KEY=701100035871000563073&

2.1.2.2.1.png
执行下面的命令以确定您系统对应所需下载的组件
vml3158:~ # uname -a

Linux vml3158 3.0.101-0.46-default #1 SMP Wed Dec 17 11:04:10 UTC 2014 (8356111) x86_64 x86_64 x86_64 GNU/Linux)

通过加压最新的SUM获取SAPuptool:

SAPCAR -xvf SUM.SAR /sapcd/SUM10_SP13

以下为分拆表命令的示例:

/sapcd/SUM10_SP13/SUM/abap/bin/SAPuptool splittable table =<table_name> segmentsize=0.2 nocntlines whereFile=<table_name>

  

下面是在SWPM中调用SAPuptool的步骤:.

2.1.2.2.2.png

2.1.2.2.3.png2.1.2.2.4.png

2.1.2.2.5.png
导入分拆表文件
以下为测试示例:

2.1.2.2.6.png

REPOSRC%10 表示将表REPOSRC分拆成10片。
如果想以固定的条目数来拆分,可使用:
<TABLENAME>:<每个分片条目数>。
2.1.2.2.7.png

勾选Use SAPuptool from SUM,并提供已下载解压后的文件路径以启用SAPuptool。

2.1.2.2.8.png

检查参数。

2.1.2.2.9.png

完成分拆表。


现在到出媒介中将包含用于并行导出表的文件<table_name>.WHR,及之前进行了分拆表表目的文件whr.txt。

2.1.2.2.10.png

2.1.2.2.11.png

2.1.2.2.12.png

   

2.1.2.3 Database Instance Export

2.1.2.3.1.png

2.1.2.3.2.png

2.1.2.3.3.png

2.1.2.3.4.png

2.1.2.3.5.png

输入先前生成的SMIGR目录(2.1.1 SMIGR_CREATE_DDL)

2.1.2.3.6.png

2.1.2.3.7.png

2.1.2.3.8.png

2.1.2.3.9.png

定义分拆包的参数。在这一步,将会限定每个包的大小。

2.1.2.3.10.png

参数"Perform Parallel Export and Import"用于生产系统迁移。R3load会在目标硬件平台执行导入。

注意:

对于BW系统,我们选择 "Use Unsorted Unload" 以加速导出。如果我们不选择这个选项,表会在导出是进行排序。这意味着额外资源和时间的使用。
而这一选项仅可用于BW系统,因为BW系统没有cluster及pool 的结构。对于ERP系统,我们不能使用这一选项。此外,这也与目标系统数据库类型相关,具体内容请参阅Note 954268.

2.1.2.3.11.png

选择 "Unload Order by Size" 意味着根据导出尺寸进行排序。在第一次导出执行后,我们能分析各个包的统计时间以定义一个更优化导出次序。使得需要最长时间的job能在最开始运行。

2.1.2.3.12.png

job总是是基于CPU使用率和I/O吞吐量。一般来说,在导出时系统为下线状态,因此当CPU使用率都到达95%时,意味着系统资源几乎被完全使用。

此处sapinst会读取"CustomSortOrder.txt"以确定导出次序。我们可以根据之前运行的结果来定义这个文件。一般将最大,耗时最长的表加入这个文件中。

2.1.2.3.13.png

2.1.2.3.14.png

2.1.2.3.15.png

选项"-merge_bck"用于确保TSK文件在job意外中断时的数据一致性。

2.1.2.3.16.png

检查参数配置。

2.1.2.3.17.png

2.1.2.3.18.png

停止BW系统。

2.1.2.3.19.png

仅启动数据库(Oracle)

2.1.2.3.20.png

导出完毕。

2.1.2.3.21.png

2.1.2.3.22.png

2.1.2.3.23.png

2.1.2.3.24.png

2.1.2.3.25.png

2.1.2.3.26.png

你会发现,由SMIG_GREATE_DDL生成的文件被复制到了这个导出的文件夹。

   

2.2. 导入目标系统 (BW on HANA)


2.2.1 设置OS环境变量

在使用SWPM进行导入前,需要设置如下变量。

HDB_MASSIMPORT, 此参数参考Note 1775293及link:Migration to SAP HANA: Latest News about SAP Note 1775293

_JAVA_OPTIONS,此参数参考link:RUNNING WITH JAVA

2.2.1png.png


2.2.2 设置HANA系统参数

建议将log_mode在进行import时临时修改为overwrite,以避免在导入过程中生成大量log backup文件。

2.2.2png.png


2.2.3 设置Table Placement

此处需要按照您HANA系统架构(单机或是集群;集群中包含多少worker节点)解压出Note1908075中对应的HdbTablePlacementParameters.SQL 文件。

2.2.3.1.png

2.2.3.2.png

2.2.3.3.png


2.2.4 执行SWPM

2.2.4.1.png

2.2.4.2.png

2.2.4.3.png

2.2.4.4.png

2.2.4.5.png

2.2.4.6.png

2.2.4.7.png

2.2.4.8.png

2.2.4.9.png

2.2.4.10.png

这里将路径设置为在之前步骤2.1.2中导出媒介所在路径。

2.2.4.11.png

2.2.4.12.png

2.2.4.13.png

2.2.4.14.png

2.2.4.15.png

将路径设置为先前解压文件HdbTablePlacementParameters.SQL所在路径。

2.2.4.16.png

下载Note1958346中附件HdbLandscapeReorgCheckProcedure.SQL,并设置对应路径。

2.2.4.17.png

2.2.4.18.png

2.2.4.19.png

2.2.4.21.png

此处需要指定SAPEXE.SAR以及SAPEXEDB.SAP路径到下载的kernel 文件路径。

在解压从service market place后,这两个文件的文件路径如下:

SAPEXE.SAR:/DATA_UNITS/K_7XX_U_LINUX_X86_64/DBINDEP/

SAPEXEDB.SAP:/DATA_UNITS/K_7XX_U_LINUX_X86_64/HDB/


2.2.4.20.png

2.2.4.22.png

2.2.4.23.png

2.2.4.24.png

2.2.4.25.png

导入完成。







   

3.常见问题及处理


3.1 时区设置

3.1.1问题描述:

若application server时间设置与HANA DB 时区设置不一致,会出现如下错误信息。

3.1.png

3.1.2解决方法:

调整HANA时区设置。以HANA <sid>adm用户登录,并修改在home目录(/usr/sap/<SID>/home)下的两个文件(.sapenv.csh, .sapenv/sh),调整时区设置。

.sapenv.csh: setenv TZ <time zone>

.sapenv.sh: export TZ=<time zone>

修正后,需要重启HANA数据库以使时区设置生效。

如下信息可供参考:

1801227 - Change Time Zone if SID is not changed via Config. Tool

1829651 - Time zone settings in HANA scale out landscapes

1791342 - Time Zone Support in HANA

1932132 - SAP HANA : Large time difference between application server and HANA database.

 

3.2 HANA client 安装媒介缺损

3.2.1问题描述:

在安装过程中,步骤“Install SAP HANA Database Clinet”失败。

3.2.png

3.3.png

手动安装显示如下错误:

vml3158:/sapmnt/vml3158/a/installfile # ./hdbinst

cannot exec /sapmnt/vml3158/a/installfile/./../install/sdbrun: No such file or directory

 

3.2.2解决方法:

下载完整的安装媒介。

可以通过手动安装HANA client以验证媒介是否完整。

vml3158:/sapmnt/vml3158/a/installfile/hdbclient/SAP_HANA_CLIENT # ./hdbinst --batch -a client --path=/usr/sap/HBW/hdbclient --sid=HBW

 

3.3 Migration Key

3.3.1问题描述:

安装过程中报错:

3.4.png

3.3.2解决方法:

参考如下notes输入正确migration key。

1899381 - How to check migration key issues during a System Copy

1134948 - ABAP Migration Key for special installation numbers (SAP internal)


   

在SAP Help Portal  ( http://help.sap.com/hana_platform/) 中可以看到SAP HANA最新版本的相关文档。

如果您需要查看HANA非最新版本的对应文档时,可以通过如下路径直接下载到之前所有版本的完整文档。

SAP Service Marketplace -> Products -< Installation & Upgrade Guides -> SAP In-Memory Computing

-> SAP In-Memory Appliance (SAP HANA).

Docu Path.jpg

   

MCOD ( Multiple Components on One Database),

Database Software 和 Database Runtime Components 是共享的,并使用同一套硬件。

 

MCOS (Multiple Components on One System),

Database Software 和 Database Runtime Components是非共享的。

 

MCOD&MCOS.JPG

     
Whisly Wei

SAP HANA中的文本挖掘

发贴人 Whisly Wei 2015-8-7

     在SAP HANA中,除了基本的分词等文本分析任务外,从SPS09开始增加了文本挖掘(Text Mining)的功能。具体来说,具体来说包括文本关键词提取,文本分类,相似文本查找,相似单词查找等功能,在SPS09中,文本挖掘接口以XS接口的形式提供,在SPS10中,提供了SQL形式的接口,这对于文本挖掘的任务,真是非常cool, 有了这个神器,文本分类不再需要整合R,直接在HANA中就可以实现文本分类的功能,具体来说,在HANA内部,在建立全文索引之后,维护了一个term-document矩阵,基于此,可以计算TF,IDF,TF-IDF等词项权重,以欧几里得距离为基础,实现K近邻分类。

      废话不多说,下面直接见例子,本文只是介绍最基本用法为主,更多参数及原理请读者自行查找相关资料。


- 准备数据

  1. SET SCHEMA TMTEST;  
  2. DROP TABLE MYTEST CASCADE;  
  3. CREATE COLUMN TABLE MYTEST(ID INTEGER primary key,CONTENT NCLOB,LANG VARCHAR(32),CLASS VARCHAR(64));  
  4. INSERT INTO MYTEST VALUES('1','I am a chinese, I live in beijing','en','china');  
  5. INSERT INTO MYTEST VALUES('2','I like fish,especially big fish','en','fish');  
  6. INSERT INTO MYTEST VALUES('3','fish is an animal,live in water','en','fish');  
  7. INSERT INTO MYTEST VALUES('4','fish is delicous, I like it','en','fish');  
  8. INSERT INTO MYTEST VALUES('5','Chinese is great, I like chinese','en','china');  
  9. INSERT INTO MYTEST VALUES('6','China and Chinese','en','china');  

我们插入6条记录,属于俩个大类,‘china’跟'fish'.


二 建立全文索引

  1. DROP FULLTEXT INDEX ftidx;  
  2. CREATE FULLTEXT INDEX ftidx ON MYTEST (CONTENT)  
  3. ASYNC  
  4. FAST PREPROCESS OFF  
  5. SEARCH ONLY OFF  
  6. TEXT ANALYSIS ON  
  7. CONFIGURATION 'LINGANALYSIS_FULL'  
  8. TEXT MINING ON  
  9. TEXT MINING CONFIGURATION 'DEFAULT.textminingconfig'  
  10. LANGUAGE DETECTION ('EN')  


具体参数意义请参考相关文档,我就不一个一个解释了,主要是关闭FAST PREPROCESS,关闭SEARCH ONLY,打开TEXT ANALYSIS跟TEXT MINING,文本挖掘配置参数文件用默认的。


三 Delta Merge

  1. MERGE DELTA OF MYTEST;  

记住,这一步非常重要!!!!!


四 相关功能函数


(1) 输入一个单词,找出相关的单词。

例如找出fish的相关单词

relatedterm.jpg

(2) 输入一篇文章,找出文章中重要的单词

例如,找出ID=3的文章中的重要单词

relevent-term.jpg


(3) 输入字符开头,找出推荐的单词

例如找出C开通的单词

sugguest.jpg

(4) 以文找文,输入一篇文章,找出相似文章

relate-doc.jpg

(5) 以词找文

relevent-doc8.jpg


(6) kNN分类算法

kNN.jpg

在上例子中,我们的训练集合中就两类,fish跟china。然后我们想看看water是哪个类别,在结果的CATEGORY_VALUE中看到是fish这一类的。


全部SQL代码参考附件textmining.sql

参考资料:

 

http://help.sap.com/hana/SAP_HANA_Text_Mining_Developer_Guide_en.pdf

http://help.sap.com/hana/SAP_HANA_SQL_and_System_Views_Reference_en.pdf

 

[本文的测试案例所使用的SAP HANA版本为SAP HANA SPS10]

 

想获取更多SAP HANA学习资料或有任何疑问,请关注新浪微博@HANAGeek!我们欢迎你的加入!

转载本文章请注明作者和出处http://scn.sap.com/community/chinese/hana/blog/2015/08/07/sap-hana%E4%B8%AD%E7%9A%84%E6%96%87%E6%9C%AC%E6%8C%96%E6%8E%98

请勿用于任何商业用途。

     

本文英文版

 

大家好,在这篇文章里,笔者将和大家分享如何自定义SAP HANA登陆界面背景。过程很简单,只需三步即可完成。在SAP HANA SPS08里面,我们是不能修改登陆界面背景的。所以,每次访问XS应用的时候,一直会看到如下的登陆界面。

 

0.PNG

 

那么在SAP HANA SPS09里面,首先默认的登陆界面改成了如下十分简洁的蓝色主题。同时,从SAP HANA SPS09开始,也提供给用户修改背景的能力,用户可以使用任意图片。 

 

0_1.png

 

读者可以从 SAP HANA XS Configuration Parameters - SAP HANA Administration Guide - SAP Library 获取相关的信息,如下图所示。

 

0_3.png

 

第一步:上传图片并且设置权限

首先需要明确一点,对于单个SAP HANA实例来说,所有XS应用的登陆界面都是相同的。这也就意味着背景图片和你的XS项目是没有关系的,应该放在一个全局的地方,比如官方文档中推荐的"/sap/hana/xs/ui/Image.jpg"。为了简化操作,笔者使用了自己的一个XS项目。

 

1_.png

 

可能大家已经注意到在官方文档中有一个必要条件"No requirement for authentication and authorization"。所以,我们必须先设置该图片为公开权限,就是不需要登陆就能访问的权限。那么,通过修改.xsaccess文件就可以做到,具体为修改authentication字段为null。

 

.xsaccess

2.PNG

 

第二步:配置xsengine.ini -> httpserver -> login_screen_background_image

如下图所示,设置login_screen_background_image参数为图片存放的路径

 

3_.png

 

第三步:设置technical用户

创建一个technical用户,比如“_USS”,然后赋予其"sap.hana.xs.selfService.user.roles::USSExecutor"角色

 

4_.png

 

将该用户赋给"/sap/hana/xs/selfService/user/selfService.xssqlcc"

 

5_.png

 

大功告成!随便访问一个XS应用来测试一下吧!

 

6_1.PNG

 

 

 

想获取更多SAP HANA学习资料或有任何疑问,请关注新浪微博@HANAGeek!我们欢迎你的加入!

 

转载本文章请注明作者和出处,,请勿用于任何商业用途。

http://scn.sap.com/community/chinese/hana/blog/2015/04/30/%E8%87%AA%E5%AE%9A%E4%B9%89sap-hana%E7%99%BB%E9%99%86%E7%95%8C…

   

本文英文版

 

大家好,新年快乐!

 

每逢新春佳节,我们都会发一些新年祝福语给家人、朋友和同事,最常见的就是新年快乐,恭喜发财之类的,当然也会收到许多别人的祝福。笔者自从有了手机,每年除夕都会做这件事情,不发的话总感觉缺了点什么。众所周知,SAP HANA有文本分析功能,春节在家闲着无聊,一个念头闪过,SAP HANA可以分析新年祝福语吗?笔者做了一些测试,均以失败告终,但是好消息是我们可以在SAP HANA文本分析里面做定制化,从而让SAP HANA能够识别和分析新年祝福语。在本文中,笔者将和大家分享如何在SAP HANA里面定制化文本分析,让SAP HANA为我们送上新年祝福。

 

有趣的争论,到底哪种羊?

在我们切入正题之前,让我们先看一个有趣的争论。大年初一当笔者打开Chrome的时候,出现了下面的Google doodle,呵呵,Google也和我们一起庆祝农历新年。 不过现在已经看不到这个Google doodle了,如果大家还想回味一下的话,可以访问 Lunar New Year 2015 和 Google Doodle Rings in Chinese Lunar New Year. 那么有趣的争论到底是什么呢?大家知道,今年是羊年,中国人就叫羊年,可是老外弄不明白了,到底中国的羊年是哪一种羊呢?到底是公羊(Ram)、绵羊(Sheep)还是山羊(Goat)?哈哈,详见 Whatever Floats Your Goat: The 2015 Lunar New Year Animal Is Up For Debate : Code Switch : NPR

 

1.PNG

来自SAP HANA的祝福 - 定制化文本分析EXTRACTION_CORE

我们将在该节讨论如何通过定制化文本分析EXTRACTION_CORE来收到SAP HANA的祝福。首先,让我们看一下在没有定制化的情况下会发生什么。本文所有测试都基于 SAP HANA SPS 09 Rev. 91。

 

  1. DROP SCHEMA TA CASCADE;  
  2. CREATE SCHEMA TA;  
  3. SET SCHEMA TA;  
  4. CREATE COLUMN TABLE TA_TABLE (  
  5.   ID INTEGER PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,  
  6.   CONTENT NVARCHAR(200),  
  7.   LANG NVARCHAR(2)  
  8. );  
  9. INSERT INTO TA_TABLE (CONTENT, LANG) VALUES ('新年快乐''ZH');  
  10. INSERT INTO TA_TABLE (CONTENT, LANG) VALUES ('恭喜发财''ZH');  
  11. CREATE FULLTEXT INDEX TA_INDEX ON TA_TABLE (CONTENT)  
  12. CONFIGURATION 'EXTRACTION_CORE'  
  13. LANGUAGE COLUMN LANG  
  14. TEXT ANALYSIS ON;  
  15. SELECT * FROM "$TA_TA_INDEX";  

 

通过上面的SQL语句,我们首先建了一张带有语言字段(LANG)的原始表,接着插入了两条祝福语,新年快乐和恭喜发财,然后我们创建了一个全文索引来做文本分析,该全文索引基于原始表中的CONTENT字段,配置为EXTRACTION_CORE。大家可以从 Text Analysis - SAP HANA Text Analysis Developer Guide - SAP Library找到目前所有可用的配置。下图是我们查询文本分析的结果表,大家可以从 Structure of the $TA Table - SAP HANA Text Analysis Developer Guide - SAP Library 找到所有列的解释。从图中可以发现,SAP HANA没有解析出任何内容,原因很简单,因为在SAP HANA预先定义的 predefined entity types 里面没有GREETING。

 

2.PNG

 

那么我们现在可以做什么呢?我们可以从 SAP HANA Text Analysis Extraction Customization Guide - SAP Library 中找到答案,该文件展示了如何定制化文本分析的解析。这里还有一个视频详细介绍了该方法 SAP HANA Academy - Text Analysis: 10. Custom Dictionaries - YouTube 下面就让我们自己来一步步实现。

 

步骤一:创建XS项目

 

3_1.png

 

步骤二:创建.hdbtextdict文件,即自定义词典。在该文件中,我们可以定义自己的 TA_TYPE(entity_category) 和 TA_TOKEN(entity_name)。比如,我们定义了"GREETING"这个entity_category, 定义了"新年快乐"和"恭喜发财"这两个entity_name。

 

3_2.png

 

GREETING.hdbtextdict

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <dictionary xmlns="http://www.sap.com/ta/4.0">  
  3.   <entity_category name="GREETING">  
  4.   <entity_name standard_form="新年快乐">  
  5.   </entity_name>  
  6.   <entity_name standard_form="恭喜发财">  
  7.   </entity_name>  
  8.   </entity_category>  
  9. </dictionary>  

 

步骤三:创建.hdbtextconfig文件,即自定义配置。在该文件中,我们需要引入步骤二中的.hdbtextdict文件。本例中,我们复制了SAP HANA标准的 EXTRACTION_CORE (sap.hana.ta.config::EXTRACTION_CORE),然后引入我们的自定义词典。

 

3_3.png

 

EXTRACTION_CORE_CUSTOM.hdbtextconfig

  1. ...  
  2.     <!-- List of repository objects containing Text Analysis extraction dictionaries. -->  
  3.     <property name="Dictionaries" type="string-list">  
  4.         <string-list-value>TACustom::GREETING.hdbtextdict</string-list-value>  
  5.     </property>  
  6. ...  

 

步骤四:使用步骤三中的自定义配置来创建全文索引。

  1. DROP FULLTEXT INDEX TA_INDEX;  
  2. CREATE FULLTEXT INDEX TA_INDEX ON TA_TABLE (CONTENT)  
  3. CONFIGURATION 'TACustom::EXTRACTION_CORE_CUSTOM'  
  4. LANGUAGE COLUMN LANG  
  5. TEXT ANALYSIS ON;  
  6. SELECT * FROM "$TA_TA_INDEX";  

 

如下图所示,现在我们可以收到来自SAP HANA的祝福啦。

 

4_1.png

 

当然,除了这两个祝福语之外还有许许多多祝福语,用户可以丰富自己的自定义词典,即.hdbtextdict文件.

 

来自SAP HANA的情感 - 定制化文本分析EXTRACTION_CORE_VOICEOFCUSTOMER

我们知道SAP HANA文本分析中最强的武器是情感分析。现在我们已经得到了SAP HANA的祝福,那么对于这些祝福,SAP HANA又会分析出什么情感呢?出于好奇,笔者尝试了英语和中文两种语言,下面就让我们一起来看一下。

 

  1. INSERT INTO TA_TABLE (CONTENT, LANG) VALUES ('Happy new year''EN');  
  2. INSERT INTO TA_TABLE (CONTENT, LANG) VALUES ('Congratulations for prosperity''EN');  
  3. SELECT * FROM TA_TABLE;  

 

5.PNG

 

首先,笔者在原始表中添加了两条英语祝福,和我们原先两条中文祝福对应。 "新年快乐" 对应 "Happy new year",  "恭喜发财" 对应 "Congratulations for prosperity"。 然后我们这次创建配置为 "EXTRACTION_CORE_VOICEOFCUSTOMER" 的全文索引,让SAP HANA来做情感分析。

 

  1. DROP FULLTEXT INDEX TA_INDEX;  
  2. CREATE FULLTEXT INDEX TA_INDEX ON TA_TABLE (CONTENT)  
  3. CONFIGURATION 'EXTRACTION_CORE_VOICEOFCUSTOMER'  
  4. LANGUAGE COLUMN LANG  
  5. TEXT ANALYSIS ON;  
  6. SELECT * FROM "$TA_TA_INDEX";  

 

从如下的分析结果,我们可以发现SAP HANA从两条新插入的英语祝福语中成功分析出了情感,但是原先的两条中文祝福语却没有分析出情感。深入分析的话,SAP HANA在两条英语祝福语中分析出了具体是哪种情感(红框标注)和情感所形容的具体主题。另外还可以发现在 SAP HANA SPS09中有一个改进,那就是TA_PARENT字段。有了这个字段,我们可以非常方便的绑定情感和主题。那么下面让我们来具体看一下。

 

  • 对于 "Happy new year", "Happy" 是一个弱正面情感(weak positive sentiment)。然后为什么快乐呢?为新年 "new year"。
  • 对于 "Congratulations for prosperity", "Congratulations" 也是一个弱正面情感(weak positive sentiment)。然后恭喜什么呢?恭喜发财 "prosperity".

6_1.png


看起来SAP HANA完美支持了英语的情感分析,那么对于中文呢?别担心,我们依旧可以像在上节中定制化EXTRACTION_CORE一样来定制化EXTRACTION_CORE_VOICEOFCUSTOMER。因为中文是一种非空格语言(non-whitespace language), 我们需要查看 Sentiment Analysis Customization in Nonwhitespace Languages。那么我们想让SAP HANA也分析出来和英文类似的结果。

  • 对于 "新年快乐", "新年" 等同于 "new year", "快乐" 等同于 "happy"。
  • 对于 "恭喜发财", "恭喜" 等同于 "congratulations", "发财" 等同于 "prosperity"。

那么,让我们来尝试一下。


步骤一:创建自定义词典,即.hdbtextdict文件。该文件的XML结构和上节的 GREETING.hdbtextdict相同。但是在情感分析中,我们只能使用如下五种entity_category:

  • CustomTopic
  • CustomPositive
  • CustomNegative
  • CustomNeutral
  • CustomProblem

 

7_2.png

 

GREETING_VOC.hdbtextdict

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <dictionary xmlns="http://www.sap.com/ta/4.0">  
  3.   <entity_category name="CustomTopic">  
  4.   <entity_name standard_form="新年">  
  5.   </entity_name>  
  6.   <entity_name standard_form="发财">  
  7.   </entity_name>  
  8.   </entity_category>  
  9.   <entity_category name="CustomPositive">  
  10.   <entity_name standard_form="快乐">  
  11.   </entity_name>  
  12.   <entity_name standard_form="恭喜">  
  13.   </entity_name>  
  14.   </entity_category>  
  15. </dictionary>  

 

步骤二:创建自定义配置,即.hdbtextconfig文件。和上节的.hdbtextconfig文件类似,我们先复制SAP HANA标准配置EXTRACTION_CORE_VOICEOFCUSTOMER (sap.hana.ta.config::EXTRACTION_CORE_VOICEOFCUSTOMER) 然后引入我们的自定义词典。

 

7_3.png

 

EXTRACTION_CORE_VOC_CUSTOM.hdbtextconfig

  1. ...  
  2. <!-- List of Text Analysis extraction dictionaries for Sentiment Analysis. -->  
  3.     <property name="Dictionaries" type="string-list">  
  4. ...  
  5.       <string-list-value>TACustom::GREETING_VOC.hdbtextdict</string-list-value>  
  6.     </property>  
  7. ...  

 

步骤三:使用步骤二中的自定义配置来创建全文索引。

  1. DROP FULLTEXT INDEX TA_INDEX;  
  2. CREATE FULLTEXT INDEX TA_INDEX ON TA_TABLE (CONTENT)  
  3. CONFIGURATION 'TACustom::EXTRACTION_CORE_VOC_CUSTOM'  
  4. LANGUAGE COLUMN LANG  
  5. TEXT ANALYSIS ON;  
  6. SELECT * FROM "$TA_TA_INDEX";  

 

8_1.png

 

虽然我们可以在TA_TYPE字段中找到 "CustomTopic" and "CustomPositive",分析的结果不完全正确,分析结果不太满意。我们需要的是类似英语的那种分析结果。那么为什么分析结果会不同呢?原因是我们只定义了自定义词典,但是对于情感分析来说还有其他因素,比如解析规则等。为了简便,我们可以在两条中文祝福语中稍加修改来达到目的。

 

  1. INSERT INTO TA_TABLE (CONTENT, LANG) VALUES ('新年很快乐''ZH');  
  2. INSERT INTO TA_TABLE (CONTENT, LANG) VALUES ('恭喜你发财''ZH');  
  3. SELECT * FROM "$TA_TA_INDEX";  

 

9_1.png

 

现在我们就可以发现和英文差不多的分析结果了。SAP HANA在两条中文祝福语中都分析出了具体情感和主题。这就是我们想要的!

 

总结

在本文中,我们定制化了两种SAP HANA文本分析的配置,EXTRACTION_CORE 和 EXTRACTION_CORE_VOICEOFCUSTOMER。通过对文本分析的定制化,我们在农历新年收到了来自SAP HANA正面情感的祝福。


希望这篇文章对大家理解SAP HANA的文本分析有所帮助。祝大家新年快乐,恭喜发财! 

 

happynewyear.gif

gongxi.gif

 

Image source

 

想获取更多SAP HANA学习资料或有任何疑问,请关注新浪微博@HANAGeek!我们欢迎你的加入!

 

转载本文章请注明作者和出处http://scn.sap.com/community/chinese/hana/blog/2015/03/01/%E6%9D%A5%E8%87%AAsap-hana%E7%9A%84%E6%96%B0%E5%B9%B4%E7%A5%9D…,请勿用于任何商业用途。

   
Leo Hu

SDI的部署及简单使用

发贴人 Leo Hu 2015-3-1

什么是SDI

SDI,即Smart Data Integration,是集成到HANA中的一个数据迁移和同步工具。通过SDI,我们可以用图形化的方式对远程数据源(如OracleDB2Hive等)的数据做过滤、连接、类型转换等操作,然后导入到HANA

使用SDI要做的工作

  1. 启动HANADP Server
  2. 安装配置DP Agent
  3. 注册DP Agent
  4. 注册 Adapter
  5. 创建远程数据源及虚表
  6. 创建并激活数据流图
  7. 执行存储过程

启动HANADP Server

Data Provisioning ServerHANA的一个native进程,它与DP Agent或远程数据源进行数据交互。DP ServerHANA自带组件,不需要额外安装,但默认情况下DP Serverdisabled,所以我们需要将其enable。激活方法是:Configuration选项卡àdaemon.iniàdpserveràinstances1

1.png

该属性是change online,不需要重启HANA

DP Server启动完成后可以在Services选项卡中看到dpserver的状态为active

2.png

安装配置DP Agent

1. 从SAP Software Download Center下载DP Agent安装包“data_provision_agent_xxxxxxxx.zip”。

2. 解压zip包,将其中的DATA_UNITS\HANA_DP_AGENT_10_LIN_X86_64文件夹copy到要安装的linux机器上(当然你也可以安装windows版的)。

3. 执行./hdbinst

3.png

输入安装路径。

4.png

输入用于DP Agent服务的用户名、监听端口和管理端口。

4. 进入DP Agent安装路径,运行配置工具:

5.png

5. 在弹出的对话框中点击ConfigureàPreferences

6.png

DP Agent的配置界面,你可以配置Adapter Framework和各个Adapter的参数,Adapter Framework的参数适用于所有Adapter,比如Worker Thread Pool是线程池的容量,即并行导入的最大线程数。

注册DP Agent

1. 运行DP Agent的配置工具:

7.png

8.png

2. 先要连接到一个HANA系统,点击Connect to HANA

9.png

在弹出的对话框中填入HANA系统的链接信息,这里既可以连接到On PremiseHANA,也可以连接到On CloudHANA

3. 连接HANA之后就可以看到现有的所有Adapter

10.png

然后点击Register Agent按钮,弹出对话框:

11.png

点击Register按钮完成注册,注册成功后在HANA Studio中查看视图"SYS"."AGENTS"

12.png

可以看到”srsserverAgent”已经成功注册到HANA系统。

注册Adapter

DP Agent注册成功后,还需要将要连接的远程数据源对应的Adapter注册到HANA系统。

1. 将要连接的数据源的JDBC驱动文件(例如OracleJDBC驱动文件ojdbc6.jar)拷贝到DP Agent安装目录的lib子文件夹下:

<DP_AGENT_INSTALL_DIR>/lib

默认为:/usr/sap/dataprovagent/lib

2. 在配置工具界面的Adpaters列表中选择远程数据源的Adapter,例如,要连接Oracle则选择OracleLogReaderAdapter,然后点击Register Adapter按钮。

13.png

3. Adapter注册成功后,在HANA中查看视图"SYS"."ADAPTERS"

14.png

可以看到OracleLogReaderAdapter已经成功注册到HANA系统。

创建远程数据源及虚表

1. 创建SDI远程数据源和创建SDA远程数据源类似,在Adapter Name栏选择远程数据源对应的Adapter,例如连接Oracle则选择OracleLogReaderAdapter

2. Oracle数据源为例,Instance NameDP Agent中创建的实例名称,你可以使名称和数据源名称一致,Administration Port是该instance的管理端口,默认是13456

15.png

3. 创建虚表方法和SDA一致。

创建并激活数据流图

1. 在repositoryHANA XS project中新建一个数据流图:

16.png

17.png

18.png

2. 使用拖拽的方式构建一个数据流图:

19.png

可以选中各个节点,然后在其属性框中设置其属性,例如,JOIN节点的属性框如下所示:

20.png

3. 保存并激活数据流图:

21.png

执行存储过程

1. 数据流图成功激活后,我们在数据流图所在的schema下可以看到生成了一个存储过程:

22.png

2. 存储过程内容如下:

CREATE PROCEDURE "SDI"."LEO.SDI::sdi_fg1"()

LANGUAGE SQLSCRIPT SQL SECURITY INVOKER

AS

BEGIN

ORCL_DS_TSTTAB_DATA_TAB = SELECT "ID""NAME" FROM "SDI"."orcl_ds_TSTTAB";

ORCL_DS_TSTTAB_2_DATA_2_TAB = SELECT "ID""NAME" FROM "SDI"."orcl_ds_TSTTAB";

SORT_OUTPUT_TAB=SELECT "ID""NAME" FROM :ORCL_DS_TSTTAB_DATA_TAB ORDER BY "ID" ASC;

JOIN_OUTPUT_2_TAB = SELECT "INPUT1"."ID" AS "ID""INPUT2"."NAME" AS "NAME_2" FROM(:SORT_OUTPUT_TAB AS "INPUT1" INNER JOIN :ORCL_DS_TSTTAB_2_DATA_2_TAB AS "INPUT2" ON"INPUT1"."ID"="INPUT2"."ID");

SELECT "ID" AS "ID""NAME_2" AS "NAME_2" FROM :JOIN_OUTPUT_2_TAB INTO"SDI"."SORTED_JOINED_TSTTAB";

END

3. 调用该存储过程即可完成数据导入。

参考资料

SAP HANA EIM Administration Guide

SAP HANA Academy – Smart Data Integration/Quality : SAP ECC Replication [SPS09]

 

想获取更多SAP HANA学习资料或有任何疑问,请关注新浪微博@HANAGeek!我们欢迎你的加入!

转载本文章请注明作者和出处http://scn.sap.com/community/chinese/hana/blog/2015/03/01/sdi%E7%9A%84%E9%83%A8%E7%BD%B2%E5%8F%8A%E7%AE%80%E5%8D%95%E4%B…,请勿用于任何商业用途。

     

简介

SAP HANA XSSPS06开始引入了XSJS outbound connectivity这个非常有用的特性。通过XSJS outbound connectivity,我们可以在SAP HANA原生应用中发起HTTP/HTTPS请求去获取外部资源。这个特性使得SAP HANA和社交媒体的连接变成了可能,而且十分方便,我们可以从社交媒体上做很多有趣的分析。那么在本文中,笔者将向大家展示如何使用XSJS outbound connectivity搜索微博。


笔者去年去美国出了一次差,那是第一次去美国,周末闲得无聊想去电影院看一场电影,一时兴起用SAP HANA做了一个电影应用,然后用这个应用选了一部电影去看。这个应用的大致思路是从Twitter上爬取评价电影的微博,将其插入SAP HANA,然后使用SAP HANA自带的文本分析功能来分析情感,进而进行评分。但是,去年那个时候SAP HANA还是SPS05版本,还没有XSJS outbound connectivity功能,笔者只能用Twitter4J来连接Twitter API。要是那个时候有这个功能该多好啊!没关系,现在用这个功能来搜索微博还为时不晚,那就让我们开始吧!本文将使用Twitter作为例子,对于国内的读者来说需要先翻墙。。。


准备工作

  1. 一个SAP HANA,至少SPS06版本,本文使用SAP HANA SPS08 Rev. 80
  2. 一个Twitter账号


步骤

1.调查Twitter API

在第一步中,我们需要调查搜索微博需要使用哪个API,然后就是怎么和Twitter API交互,认证啦,授权啦这些事情。首先你可以从这里找到所有Rest API,我们想搜索微博,所以我们可以使用这个API,所有的信息都罗列的非常详细了,包括URL,参数和例子。

 

那么我们该如何调用这个API呢?可以从这里找到答案。因为我们只是搜索微博,所以我们可以使用Application-only authentication。从这个文档里面有一个包含三个步骤非常详细的例子,这恰恰就是我们所需要的。这里有一点需要注意,需要使用HTTPS来调用API v1.1,你可以从这里找到该信息。

 

2.使用Postman来模拟调用API

在第一步中,我们已经知道了如何调用Twitter API,我们可以先用Postman来测试一下。当然有很多和Postman类似的工具,你可以自由选择。所有步骤在这里已经详细描述,笔者在这里只是用一些截图总结一下。

 

a. 编码API key和API secret

首先如果你没有应用的话,你需要先创建一个应用。创建完应用,你可以在“API Keys”这个标签下找到应用的<API key>和<API secret>。笔者已经重新生成了API key和API secret,所以下图的API key和API secret已经作废。

 

1.PNG

 

然后将<API key>:<API secret>编码成Base64格式。你可以使用Base64 Decode and Encode - Online来完成。

 

2.PNG

 

b. 获取bearer token

你需要先退出Twitter账号,要不然会报错"403 Forbidden: The server understood the request, but is refusing to fulfill it.",下图的bearer token已经失效。

 

3.PNG

 

c. 用该bearer token测试GET search/tweets | Twitter Developers

测试成功,我们搜索带有#SAPHANA的微博,得到了如下结果。简单起见,我们只使用q这个参数。

 

4.PNG

 

3.设置SAP HANA使用HTTPS

截止到目前,我们已经成功使用Postman搜索了微博。为什么不用XSJS outbound connectivity来完成相同的事情呢?让我们开始吧!由于从API v1.1开始必须使用HTTPS,我们需要做的第一件事情就是让SAP HANA支持HTTPS访问,但是默认是不行的,我们需要进行配置。你可以参照这篇文章来完成该步。当你完成了该步,你应该可以做如下两件事情,如果不能说明没有配置成功。

 

a. 可以成功访问https://<hostname or IP>:43<instance number>/sap/hana/xs/admin/

b. 当你切换至“Trust Manager”标签页,没有“No valid SAP crypto configuration”错误。

 

4.创建Twitter APItrust store

在该步骤中,我们需要创建Twitter API的trust store。同样,你可以参照这篇文章来完成该步。你只需要修改一个地方,就是把https://api.github.com/换成https://api.twitter.com/

 

5.PNG

 

5.使用XSJS outbound connectivity搜索微博

我们终于到了这步。因为我们在前面几步已经完成了相当多的准备工作,这一步对我们来说就简单许多。我们只需要完成以下步骤即可,笔者是在SAP HANA Stuido里面完成的,当然读者也可以在Web IDE里面完成。项目结构如下图所示:

 

6.PNG

 

a. 创建XS项目

b. 创建.xsapp, .xsaccess和services目录

c. 创建twitterApi.xshttpdest,编辑,保存,激活

 

description = "twitter api";

host = "api.twitter.com";

port = 443;

pathPrefix = "/1.1";

useProxy = true;

proxyHost = "proxy.pal.sap.corp";

proxyPort = 8080;

authType = none;

useSSL = true;

timeout = 0;

 

d. 在下图红框里面编辑trust store,保存

 

7.PNG

 

e. 创建search.xsjs,编辑。从Application-only authentication | Twitter Developers,我们可以得知bearer token除非被注销,要么对于应用来说是一直有效的,所以我们不必每次都去获取bearer token,我们可以直接在代码里使用bearer token。

 

var destination = $.net.http.readDestination("searchTweets.services", "twitterApi");

var client = new $.net.http.Client();

var request = new $.net.http.Request($.net.http.GET, "/search/tweets.json?q=%23SAPHANA");

request.headers.set('Authorization', 'Bearer AAAAAAAAAAAAAAAAAAAAADa7RAAAAAAAUhLkOYDVULCmK2KnNlce6dURp7Y%3Dp1ERxtaQ0IdJMAi1EdZLjT4GDt1ketu1DzzPjNqHTk');

var response = client.request(request, destination).getResponse();

$.response.status = response.status;

$.response.contentType = response.contentType;

$.response.setBody(response.body.asString());

 

f. 保存,激活所有文件

 

6.测试

现在我们就可以来测试XSJS outbound connectivity了。测试成功,发现有一条微博是“The only limitation is our imagination!”,是笔者很欣赏的一句话。


8.PNG


总结

在本文中,我们成功使用XSJS outbound connectivity来搜索微博。但是,我们并没有将搜索到的记录插入SAP HANA,当然这个是完全可以做到的。除此之外,我们还可以用XSJS outbound connectivity来调用其他Twitter API




想获取更多SAP HANA学习资料或有任何疑问,请关注新浪微博@HANAGeek!我们欢迎你的加入!

转载本文章请注明作者和出处http://scn.sap.com/community/chinese/hana/blog/2014/12/02/%E4%BD%BF%E7%94%A8sap-hana-xs%E6%90%9C%E7%B4%A2%E5%BE%AE%E5%8D…,请勿用于任何商业用途。

   
Wenjun Zhou

视图及其授权

发贴人 Wenjun Zhou 2014-11-18

在本文中,我们将和大家一起讨论视图及其授权,我们会用几个例子向大家展示如何赋予视图的权限以及什么情况下我们需要使用“WITH GRANT OPTION”语句。

 

问题描述

  1. 有三个用户,分别是用户A,用户B和用户C,每个用户拥有自己的schema
  2. 用户A在自己的schema下面创建了表A,然后将表Aselect权限赋予了用户B
  3. 用户B基于表A在自己的schema下面创建了视图B
  4. 现在问题来了。用户B可以将视图Bselect权限赋给用户C吗?那么用户C是否又能看到视图B中的数据呢?

在回答这些问题之前,让我们先在SAP HANA里面做几个实验。本文的测试案例所使用的SAP HANA版本为SAP HANA SPS8 Revision 80


实验一

步骤一:使用SYSYEM用户创建三个用户,分别是USER_A, USER_BUSER_C

CREATE USER USER_A PASSWORD Initial1;

CREATE USER USER_B PASSWORD Initial1;

CREATE USER USER_C PASSWORD Initial1;


步骤二:使用USER_A在自己的schema USER_A下面创建TABLE_A,然后将该表的select权限赋给USER_B

CREATE COLUMN TABLE USER_A.TABLE_A (ID INTEGER);

GRANT SELECT ON USER_A.TABLE_A TO USER_B;


步骤三:使用USER_B在自己的schema USER_B下面创建基于TABLE_A的视图VIEW_B

CREATE VIEW USER_B.VIEW_B AS SELECT * FROM USER_A.TABLE_A;


步骤四:使用USER_B尝试给USER_C赋予VIEW_Bselect权限,但是失败

GRANT SELECT ON USER_B.VIEW_B TO USER_C;

 

1.PNG

 

VIEW_BUSER_B创建的,那么为什么USER_B不能给USER_C赋予VIEW_Bselect权限呢?

 

原因很简单。虽然VIEW_BUSER_B创建的,但是VIEW_B是基于TABLE_A的,而USR_C对于TABLE_A是没有任何权限的。试想一下,如果USER_B成功运行了步骤四中的SQL语句,那么权限将不复存在。因为任何用户都可以使用这种手段来看到任何表,比如该例中,USER_C就可以通过USER_B来创建视图的方法让其看到TABLE_A中的内容。


那么有什么办法可以让USER_C拥有VIEW_Bselect权限吗?有,而且十分简单。我们只需要让USER_AUSER_B说点什么,比如:


“兄弟,你可以自己玩我的篮球(TABLE_A),如果你和其他人(USER_C)有篮球比赛(VIEW_B),你也可以用我的篮球。”


这意味着USER_A同意USER_B让其他人一起玩USER_A的篮球。在这种场景中,我们就可以使用“WITH GRANT OPTION”了,这句语句允许被授权的人继续授权给其他人。那么,让我们来试一下。


步骤五:使用USER_A重新给USER_B赋予TABLE_Aselect权限,这次我们加上“WITH GRANT OPTION

GRANT SELECT ON USER_A.TABLE_A TO USER_B WITH GRANT OPTION;


步骤六:使用USER_C成功查看VIEW_B

SELECT * FROM USER_B.VIEW_B;


实验二

现在让我们来看另外一个例子。在这个例子中,我们先让USER_ATABLE_Aselect权限赋给USER_C,看看会发生什么。


步骤一:使用SYSTEM创建三个用户,分别是USER_A, USER_BUSER_C

CREATE USER USER_A PASSWORD Initial1;

CREATE USER USER_B PASSWORD Initial1;

CREATE USER USER_C PASSWORD Initial1;


步骤二:使用USER_A在自己的schema USER_A下面创建TABLE_A,然后将该表的select权限赋给USER_BUSER_C

CREATE COLUMN TABLE USER_A.TABLE_A (ID INTEGER);

GRANT SELECT ON USER_A.TABLE_A TO USER_B;

GRANT SELECT ON USER_A.TABLE_A TO USER_C;


步骤三:使用USER_B在自己的schema USER_B下面创建基于TABLE_A的视图VIEW_B,并且将整个schema USER_Bselect权限赋给USER_C

CREATE VIEW USER_B.VIEW_B AS SELECT * FROM USER_A.TABLE_A;

GRANT SELECT ON SCHEMA USER_B TO USER_C;


步骤四:使用USER_C尝试查看VIEW_B,但是失败

SELECT * FROM USER_B.VIEW_B;


2.PNG


这次为什么失败呢?现在你可能有些困惑,你可能这么认为:

1.因为USER_ATABLE_Aselect权限赋予了USER_C,所以USER_C应该可以查看TABLE_A。对,你说的没错。USER_C可以成功运行如下语句:

 

SELECT * FROM USER_A.TABLE_A;

 

2.因为USER_B把自己整个schema USER_Bselect权限赋给了USER_C,所以USER_C应该可以查看schema USER_B下面的所有对象。这个观点正确吗?从步骤四中的错误信息可以得出这个观点是错误的。那么错在哪里呢?


我们还是举篮球的例子。


  1. USER_AUSER_B说,“USER_B,你可以玩我的篮球。”
  2. USER_AUSER_C说,“USER_C,你可以玩我的篮球。”
  3. USER_BUSER_C说,“USER_C,你可以一直和我一起玩篮球。”


如果USER_CUSER_B一起玩USER_B的篮球,那么没有任何问题。但是如果USER_B在玩USER_A的篮球,此时USER_C可以加入一起玩吗?不行,因为USER_A没有同意USER_B让其他人一起玩USER_A的篮球。这就是原因所在。那么,我们还是需要使用“WITH GRANT OPTION”来解决该问题。


步骤五:使用USER_A重新给USER_B赋予TABLE_Aselect权限,这次我们加上“WITH GRANT OPTION

GRANT SELECT ON USER_A.TABLE_A TO USER_B WITH GRANT OPTION;


步骤六:使用USER_C成功查看VIEW_B

SELECT * FROM USER_B.VIEW_B;


实验三

假设我们现在多了一个用户USER_DUSER_C想在自己的schema USER_C下面创建一个基于VIEW_B的视图VIEW_C,而且想让USER_D查看VIEW_C。那么我们应该运行哪些SQL来实现这个需求呢?大家可以把这个实验当做课后练习,这里我们就不具体解释了,代码如下:


--SYSTEM

CREATE USER USER_A PASSWORD Initial1;

CREATE USER USER_B PASSWORD Initial1;

CREATE USER USER_C PASSWORD Initial1;

CREATE USER USER_D PASSWORD Initial1;

 

--USER_A

CREATE COLUMN TABLE USER_A.TABLE_A (ID INTEGER);

GRANT SELECT ON USER_A.TABLE_A TO USER_B WITH GRANT OPTION;

 

--USER_B

CREATE VIEW USER_B.VIEW_B AS SELECT * FROM USER_A.TABLE_A;

GRANT SELECT ON USER_B.VIEW_B TO USER_C WITH GRANT OPTION;

 

--USER_C

CREATE VIEW USER_C.VIEW_C AS SELECT * FROM USER_B.VIEW_B;

GRANT SELECT ON USER_C.VIEW_C TO USER_D;

 

--USER_D

SELECT * FROM USER_C.VIEW_C;

 

总结

基于以上的实验,我们现在来回答文章开头的问题。

  1. 如果你的视图是基于其他不是由你创建的对象,然后你想让其他人能够查看你的视图,那么你需要让基于对象的拥有者在给你赋权限的时候加上“WITH GRANT OPTION
  2. 另外,你拥有对整个schemaselect权限并不意味这你可以查看这个schema下面所有的对象


同样,你可以访问SAP HANA开发者指南得到相似的答案 Object Privileges - SAP HANA Developer Guide - SAP Library,下面将其翻译成中文。


“一些数据库对象是基于其他对象的,比如视图通常定义为对其他表和视图的查询。对于有依赖对象操作的赋权需要对该对象和其所依赖对象的权限。对于视图来说,SAP HANA实现了标准的SQL行为。一个用户拥有对一个视图操作的赋权需要满足如下两点:

  • 用户被赋予操作该视图的权限或者角色
  • 该视图的拥有者对于该视图依赖的对象具有WITH GRANT OPTION赋权”


声明:本文所介绍的视图及其权限是一种通用的机制和原理,不仅仅适用于SAP HANA,其他数据库同样适用,比如Oracle

 

 

 

想获取更多SAP HANA学习资料或有任何疑问,请关注新浪微博@HANAGeek!我们欢迎你的加入!

转载本文章请注明作者和出处http://scn.sap.com/community/chinese/hana/blog/2014/11/18/%E8%A7%86%E5%9B%BE%E5%8F%8A%E5%85%B6%E6%8E%88%E6%9D%83,请勿用于任何商业用途。

   


在上一篇博文SAP HANA 高可用性 (High Availability) 解决方案 () - Host Auto-Failover, 节点失效自动切换中,我们主要介绍了HANA高可用性方案中的故障恢复(Fault Recovery)的解决方案,接下来我们继续探讨另一不可或缺的部分,灾难恢复(Disaster Recovery)。

HANA支持的灾难恢复解决方案有下面三种:

  SAP HANA系统复制是一种既可以用来做错误恢复又可以用来做灾难恢复的灵活的技术,从而达到高可用性的目的。

0.jpg

SAP HANA系统复制是用来解决主系统(Primary System)出现整个数据库系统崩溃,包括硬盘损坏的场景。在这种情况下,SAP HANA利用备份系统(Secondary System)来接管主系统。在SAP HANA系统复制中,备份系统拥有自己的数据存储,这些数据都是从原始数据复制过来的。

如上图所示,备份系统与主系统拥有相同的配置和拓扑结构。这就意味着在主系统中,每一个活跃的有自己持久化层的服务器在备份系统中都有一个对应的服务器。对于每一对服务器而言,复制工作是这样完成的:首先初始化,主系统响应请求,将一个数据快照传送到备份系统中。从这个快照时间后主系统的所有改变都会被复制。主系统中的日志在持久化时,主系统会将其发送到备份系统中。主系统中的一个事务直到被复制并发送到备份系统中后,才会被提交。具体提交的时间点可以通过配置log replication mode来指定:

1.   硬盘同步模式(Synchronous on disk):主系统中的事务直到收到日志在备份系统中持久化到硬盘中的回复后才被提交。这种模式保证的了两个系统的即时一致性,代价为数据传输时间和数据在备份系统中持久化的时间。

2. 内存同步模式(Synchronous in-memory):主系统中的事务直到收到日志在备份系统中被接收并存储到内存中后才被提交。代价为数据传输时间以及数据丢失的可能。

3. 异步模式(Asynchronous):主系统的事务在发送日志后被提交,不需要等待备份系统的回复。此模式没有延迟但是有数据丢失的可能。

如果备份系统连接丢失或者备份系统崩溃,主系统在一个可配置的时限后会恢复复制。备份系统会持久化收到的日志,但是不会立刻回放日志。为了避免日志的增长,增量的数据快照会被异步的传输到备份系统中。如果备份系统要进行接管,只需要回放最近数据快照的之后的日志即可。当发生失效导致接管时,系统管理员操作备份系统将其从recovery模式转换到全操作模式。接管后,备份系统会恢复到主系统重启后的状态并开始接受查询。(系统在重启后的状态可能与重启前状态不同,例如load/unload以及import操作再重启后可能会丢失)

SAP HANA 系统复制实施

前提准备

  • 主系统和备份系统都被独立地安装并运行。
  • 两个系统中有同样数量的工作主机。这样就表示standby主机数量可以不一致。
  • 系统复制不支持一台主机上面有多个同类服务器(例如index server
  • 若是分布式系统,所以配置步骤都要在master name server节点执行。
  • 备份系统的软件版本必须不小于主系统版本。
  • 两个系统必须有相同的System IDinstance number
  • 两个系统需要有相同的.ini配置文件
  • 两个系统需要有不同的Hostname

建立SAP HANA系统复制步骤(通过hdbnsutil

A. 配置主系统

  1. log_mode属性设为“normal”,表示日志区必须被备份;(备份系统也需要此设置)

1.png

  2.  做一次初始化数据备份

2.png

3.png

4.png

  3. 使主系统支持系统复制并且给主系统一个逻辑名字(使用<sid>adm用户):

cd /usr/sap/<sid>/HDB<instance_number>/exe

./hdbnsutil -sr_enable --name=<primary_logical_name>

5.png

B. 配置备份系统

  1.使用<sid>adm关闭备份系统:

/usr/sap/hostctrl/exe/sapcontrol -nr <instance_number> -function StopSystem HDB

6.png

  2. 向主系统注册备份系统(remoteHost中若包含大写字母,改为小写字母):

cd /usr/sap/<sid>/HDB<instance_number>/exe

./hdbnsutil -sr_register --name=<secondary_logical_name> --remoteHost=<primary_host> --remoteInstance=<primary_instance_number> --mode=[sync|syncmem|async]

7.png

  3. 启动备份系统使之进入recovery mode

/usr/sap/hostctrl/exe/sapcontrol -nr <instance_number> -function StartSystem HDB

8.png

 

如果一切顺利,则在主系统的landscape中看到下图。

 

9.png


系统复制接管步骤(通过hdbnsutil

1. 在备份系统使用<sid>adm执行接管:

cd /usr/sap/<sid>/HDB<instance_number>/exe

./hdbnsutil -sr_takeover

10.png

2. 若主系统修复成功,关闭主系统。

3. 注册主系统为新的备份系统然后启动。

11.png

在新的主系统中可以看到两系统角色交换。

12.png

建立SAP HANA系统复制步骤(通过HANA Studio

A. 配置主系统

  1. 初始化数据备份

  2. 使主系统支持系统复制

13.png

  3. 为主系统设定一个逻辑名字;

14.png

B. 配置备份系统

  1. 关闭备份系统,并向第一系统注册;

15.png

16.png

  2. 填写相关参数,包括逻辑名,复制模式,主系统主机名等。然后启动备份系统。

17.png

系统复制接管(通过HANA Studio

右键点击备份系统,选择System Replication,选择Perform takeover

18.png

19.png

SAP HANA系统复制相关参数说明

对于不同的系统复制需求,可以调整相关参数,见下表。

 

配置参数

数据类型

单位

默认值

作用于系统

描述

datashipping_

min_time

_interval

int

600

Secondary

备份(Secondary)系统两次数据同步请求之间的最小时间间距。

如果datashipping_logsize_threshold参数先达到,就是logsize超过设定阈值,数据同步请求会先于最小时间间距所设定的时间点发出。

datashipping_

logsize_

threshold

int

bytes

5*1024*1024*10245GB

Secondary

备份系统两次数据同步请求之间所累积的最小日志量。

如果在datashipping_min_time_interval所设定的时间间距过完后,累积的日志大小还没超出设定的阈值,数据同步请求也会被触发。(也就是说以上两个参数不管哪个先达成,都会触发数据同步请求)

datashipping

_snapshot

_max_

retention

_time

int

120

Primary

完整地同步到备份系统的snapshot的最大保留时间。

之前同步到备份系统的snapshot只要超过这个最大保留时间就会被自动删除。如果snapshot的数据传输在超过设定的最大保留时间后还没完成,之前完成的部分并不会被删除,也就是说只有完整的snapshot才有可能被自动删除。

如果此参数设为0snapshot在完成同步传输后会马上被删除。

preload_

column_

tables

bool

true/false

true

PrimarySecondary

在主(primary)系统把此参数设为true,那么所有数据已加载到内存的表(loaded table)的相关信息都会被存放在snapshot中,然后同步到备份系统。

当备份系统也把此参数设为true之后,备份系统才会根据接收到的关于loaded table的信息来对相应的表执行数据到内存的预加载。

logshipping

_timeout

int

30

Primary

主系统等待单个log buffer传输到备份系统的最长时间,如果同步日志的请求发出后在此设定时间内没响应,系统就会默认已经出错,然后log buffer会被释放,同时系统会结束该日志同步的会话。

在备份系统与主系统的连接出错的情况下,事务日志只写到主系统,日志同步只能在连接正常后才能恢复。

如果参数enable_full_sync被设置为true,主系统就会被阻塞(停止提交已执行事务)直到与备份系统的连接恢复正常。

logshipping_

async_buffer_size

int

bytes

67108864 (64M)

Primary

在异步复制的模式下(async),负责写日志的线程将log buffer拷贝到一个过渡的内存buffer中,然后由另一个线程异步地从这个内存buffer中读取log buffer并将其发送到备份系统。

此参数就是用来设置这个存放日志的buffer空间究竟有多大;若产生日志的速度远高于发送日志的速度,设定较大的log buffer就能较长时间地应对高峰期堆积下来未发送的日志。

logshipping

_async

_wait_on

_buffer_full

bool

bool

true

Primary

此参数作用于异步复制模式下log buffer区存满的情况。

如果此参数被设为true,则主系统会一直等待直到log buffer有足够空间存入新产生的日志为止;但是这样做在高负载时有大量日志堆积在log buffer区未被处理的情况下会让主系统变慢。

如果此参数设为false,主系统为了不受影响会暂时关闭与备份系统的连接;高峰期过后备份系统会重新连上主系统,然后通过增量传输来完成同步。

reconnect

_time_interval

int

30

Secondary

如果出现网络故障而导致备份系统与主系统的连接中断,备份系统会每隔一个时间段尝试一次重连,这个参数就是用来设置这个重连时间段的长短。

enable

_full_sync

bool

bool

false

Primary

在此参数设为true并且在同步(sync)的复制模式下,一旦备份系统与主系统的连接出现故障导致log buffer不能被发送到备份系统,正在执行的事务会被阻塞。这样做能保证在日志不能被发到备份系统的情况下,产生该日志事务也不能在主系统完成commit

SAP HANA系统复制测试

场景1:单主机系统,两系统在相同配置的两台物理机上,使用内网光纤连接(网速62MB/s,稳定),插入(INSERT)测试。

Amount of records (million)

Threads in parallel

Executed time (second)

sync

syncmem

async

No replication

              10

100

685

688

689

693

20.png

场景2:单主机系统,两系统处于远程连接(北京-上海)(网速1MB/s,不稳定),硬件相同,插入(INSERT)操作。

Amount of Transactions (million)

Threads in parallel

Executed time (second)

sync

syncmem

async

No Replication

               1

10

208

212

131

128

21.png

通过以上两个测试场景,可以看出在网速较高且稳定的网络中,系统复制在插入事务中不会影响性能。而在远程网络环境中的系统复制,syncsyncmem模式会影响性能,而async模式可达到近似no replication的性能。

 

场景3:多主机系统(2workers+1standby),使用内网光纤连接,插入(INSERT)测试。

 

Amount of Transactions (million)

Threads in parallel

Executed time (second)

sync

syncmem

async

No Replication

               10

100

1507

1511

1503

1496

22.png

通过测试可以看出对于分布式的SAP HANA系统,在高速且稳定的网络环境中,系统复制不会影响插入性能。

 

场景4:单主机系统,使用内网光纤连接,导入(IMPORT)测试。

Amount of records (million)

Threads in parallel

Executed time (second)

sync

syncmem

async

No replication

100(5.2G)

80

  1. 40.9

22

22~46

  1. 18.9

23.png

 

场景5 单系统主机,两系统处于远程连接(北京-上海),硬件相同,导入(IMPORT)测试。

Amount of records (million)

Threads in parallel

Executed time (second)

sync

syncmem

async

No replication

10524M

25

486

471

465

9

24.png

 

根据以上两个场景的实验结果,在高速且稳定的网络环境中,系统复制会影响Import操作的性能,在低速不稳定的网络环境中,import操作性能远远低于无复制系统。

场景6:备份系统接管(Takeover)测试

单主机系统

25.png

 

多主机系统(2workers +1 standby

26.png

根据测试结果,备份系统的接管与系统的数据量没有关系,这是因为备份系统的接管过程主要工作是回放上一次savepoint之后的redo log

结论以及帮助

  • 在网络方面,根据测试结果,本地光纤连接与远程公共网络连接两种网络环境中,系统复制性能和稳定性相差很大,推荐使用独占的端到端高速网络,并且该网络使用隔绝其他网络接入,加密,认证等安全措施。如果需要在远程网络进行系统复制,推荐使用async模式,如果系统有大量的import等高系统资源消耗的操作,建议先关闭系统复制,等操作结束后,可继续进行系统复制。
  • 根据测试结果如果网络速度不是瓶颈的话,不同类型的复制同步模式对于普通事务来讲有相近的性能。推荐使用sync模式,提供更高的安全性和稳定性。如果远程、不稳定的网络环境,则推荐使用async模式,以保证较高性能。
  • 根据测试,接管时间是很稳定的,与HANA数据量关系不大。但是在初始化replication时,备份系统会将主系统的数据进行full replication,这段时间,备份系统使不可以接管的。
  • 我们可以在多主机的SAP HANA系统中设置系统复制,与此同时,SAP HANA内部可以使用auto-failover 功能以得到更高的可用性。
  • 同时我们也可以在备份系统的基础上增加更多的系统复制以提高可用性。步骤与之前介绍一致,但需要注意,第三系统是以备份系统作为主系统建立的系统复制,第三系统与备份系统之间只能使用async模式进行复制。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值