华为云用户手册

  • 使用DRS从数据库导入数据至Elasticsearch 数据复制服务 (Data Replication Service,简称DRS)是一种易用、稳定、高效、用于数据库在线迁移和数据库实时同步的云服务。实时同步是指在不同的系统之间,将数据通过同步技术从一个数据源复制到其他数据库,并保持一致,实现关键业务的数据实时流动。 使用DRS支持将多种关系型数据库的数据导入至Elasticsearch集群,源数据库和目标集群的版本支持情况请参见表2。 表2 使用DRS从数据库导入数据至Elasticsearch 数据导入场景 源数据库 目标Elasticsearch集群 参考文档 将RDS for MySQL数据库的数据导入到 CSS Elasticsearch集群 RDS for MySQL 5.5、5.6、5.7、8.0版本 ElasticSearch 5.5、6.2、6.5、7.1、7.6、7.9、7.10版本 将MySQL同步到 CS S/ES 将TaurusDB数据库的数据导入到CSS Elasticsearch集群 TaurusDB主备实例 ElasticSearch 5.5、6.2、6.5、7.1、7.6、7.9、7.10版本 将TaurusDB同步到CSS/ES 将自建MySQL数据库的数据导入到CSS Elasticsearch集群 本地或ECS自建MySQL数据库 5.5、5.6、5.7、8.0版本 ElasticSearch 5.5、6.2、6.5、7.1、7.6、7.9、7.10版本 将MySQL同步到CSS/ES
  • Elasticsearch集群内核支持的监控指标 表1 集群内核支持的监控指标 指标名称 描述 支持的集群版本 相关文档 search请求的P99时延 开源Elasticsearch在监控search请求时仅提供了平均延迟指标,这不足以准确反映集群的实际搜索性能。为了改进这一点,CSS服务新增了P99延迟监控特性,能够有效地监控集群search请求的第99百分位延迟。 Elasticsearch 7.6.2、Elasticsearch 7.10.2 监控P99时延 集群HTTP状态码 通过HTTP对Elasticsearch的访问会收到响应和相应的状态码,但开源的Elasticsearch原生不支持对这些状态码进行统计,导致无法精确掌握接口调用的具体状况,用户也无法通过监控了解集群的整个请求情况。为了改进这一点,CSS服务新增了HTTP状态码监控功能,能够获取HTTP状态码统计信息。 Elasticsearch 7.6.2、Elasticsearch 7.10.2 监控HTTP状态码 集群索引 索引监控功能用以监测集群索引的运行状态和变化趋势,评估业务使用情况,并能够协助及时发现并处理潜在风险,确保集群稳定运行。索引监控会收集索引的stats信息,并将其存储在集群的监控索引(索引名称是“monitoring-eye-css-[yyyy-mm-dd]”)。默认情况下,这些监控索引将保留一周时间,过期会直接删除。 Elasticsearch 7.6.2、Elasticsearch 7.10.2 配置Elasticsearch集群索引监控 父主题: Elasticsearch集群支持的监控指标
  • 场景描述 重启集群支持快速重启和滚动重启,两种方案的使用说明请参见表1。建议在业务空闲时执行重启操作。 表1 重启方案 方案 使用说明 相关文档 快速重启 所有集群都支持。 当选择“节点类型”快速重启时,所选类型的所有节点会一起重启。 当选择“节点名称”快速重启时,一次只能重启一个节点。 快速重启过程中,集群不可用。 快速重启 滚动重启 仅当集群的节点数量(含Master节点、Client节点和冷数据节点)大于等于3时,才支持滚动重启。 滚动重启只支持根据“节点类型”进行重启。选择节点类型滚动重启时,所选类型的节点会依次重启。 滚动重启过程中,只有正在重启的节点不可用,不在重启过程中的节点可以正常提供服务。 当数据量比较大时,滚动重启耗时较长。 滚动重启
  • 方案概述 CSS支持存算分离,即将索引冻结到OBS来降低冷数据的存储成本。本文介绍如何使用索引生命周期管理,在特定的时间自动冻结索引,实现存算分离。 本案例通过给Elasticsearch 7.10.2版本的集群配置生命周期策略,实现索引在创建3天后,自动被冻结,数据转储到OBS中;当索引创建6天后,关闭索引;当索引创建7天后,对存储在OBS上的索引数据执行归档操作,进一步降低存储成本;当索引创建30天后,删除该索引。 图1 存算分离方案
  • 通过索引生命周期管理实现存算分离 登录 云搜索服务 管理控制台。 在左侧导航栏,选择对应的集群类型,进入集群列表页面。 在集群列表页面中,单击集群操作列的“Kibana”登录Kibana页面。 在Kibana的左侧导航中选择“Dev Tools”,进入命令执行页面。 创建生命周期策略“hot_warm_policy”。 策略定义:当索引创建3天后,自动调用冻结索引API将数据转储到OBS;当索引创建6天后关闭索引,7天后归档索引;当索引创建满30天,删除该索引。 PUT _opendistro/_ism/policies/hot_warm_policy{ "policy": { "description": "hot warm archive delete workflow", "error_notification": null, "default_state": "hot", "states": [ { "name": "hot", "actions": [], "transitions": [ { "state_name": "warm", "conditions": { "min_index_age": "3d" } } ] }, { "name": "warm", "actions": [ { "freeze_low_cost": {} } ], "transitions": [ { "state_name": "close", "conditions": { "min_index_age": "6d" } } ] }, { "name": "close", "actions": [ { "close": {} } ], "transitions": [ { "state_name": "archive", "conditions": { "min_index_age": "7d" } } ] }, { "name": "archive", "actions": [ { "freeze_archive": {} } ], "transitions": [ { "state_name": "delete", "conditions": { "min_index_age": "30d" } } ] }, { "name": "delete", "actions": [ { "delete": {} } ], "transitions": [] } ] }} 新建索引模板“template_hot_warm”。 模板定义:新建的所有“data”开头的索引会自动关联上生命周期策略“hot_warm_policy”。 PUT _template/template_hot_warm{ "index_patterns": "data*", "settings": { "number_of_replicas": 5, "number_of_shards": 1, "opendistro.index_state_management.policy_id": "hot_warm_policy" }, "mappings": { "properties": { "name": { "type": "text" } } }} 表1 参数说明 参数 说明 number_of_shards 索引分片数。 number_of_replicas 索引分片副本数。 opendistro.index_state_management.policy_id 生命周期的策略名。 新建一个索引“data-2022-06-06”,该索引会自动应用索引模板“template_hot_warm”,并通过索引模板的配置与生命周期策略“hot_warm_policy”相关联,实现索引在创建3天后冻结,6天后关闭,7天后归档,30天后删除。 POST data-2022-06-06/_bulk{"index":{}}{"name":"name1"}{"index":{}}{"name":"name2"}{"index":{}}{"name":"name3"}{"index":{}}{"name":"name4"}{"index":{}}{"name":"name5"}{"index":{}}{"name":"name6"} 查询数据,确认数据是否实现自动存算分离。 在索引创建3天后查看冻结的索引: GET _cat/freeze_indices?s=i&v 正常情况下会显示3天以前的索引已经被冻结: health status index uuid pri rep docs.count docs.deleted store.size pri.store.sizegreen open data-2022-06-06 x8ab5NX6T3Ox_xoGUanogQ 1 1 6 0 7.6kb 3.8kb 在创建索引7天后,查看索引情况: GET _cat/archive_indices?v 正常情况下会显示7天以前的索引已经被归档: health status index uuid pri rep docs.count docs.deleted store.size pri.store.size close data-2022-06-06 M0uRAWj_SKydjg0dFzyJow 在索引创建30天后,查看索引情况,正常情况下30天以前的索引已经被删除。
  • 给用户组授权 在用户组列表中,单击新建用户组“开发人员组”操作列的“授权”“权限配置”。 在用户组“选择策略”页面中,在搜索框中搜索“CSS FullAccess”和“OBS Administrator”,勾选并单击“下一步”。 创建CSS集群的权限有“CSS FullAccess”或“Elasticsearch Administrator”。 如果还需要查看资源的消费情况,请在同区域选择“BSS Administrator”权限。 设置最小授权范围。建议授权范围方案选择“指定区域项目资源”,使用哪个区域的资源就选哪个区域。 此处以仅为“华北-北京四”区域的资源设置权限为例,选择授权范围方案为“指定区域项目资源”,并选择“cn-north-4 [华北-北京四]”区域。 图1 设置最小授权范围 单击“确定”,完成用户组授权。
  • 创建 IAM 用户 A公司管理员在 统一身份认证 服务,左侧导航中,选择“用户”。 在用户页面,单击右上角“创建用户”。 图2 创建用户 配置用户基本信息。在“创建用户”界面填写“用户信息”和“访问方式”。如需一次创建多个用户,可以单击“添加用户”进行批量创建,每次最多可创建10个用户。 图3 配置用户信息 用户可以使用此处设置的用户名、邮件地址或手机号任意一种方式登录华为云。 当用户忘记密码时,可以通过此处绑定的邮箱或手机自行重置密码,如果用户没有绑定邮箱或手机号码,只能由管理员重置密码。 表1 用户信息 用户信息 说明 取值样例 用户名 必填。IAM用户登录华为云的用户名。 James、Alice 邮件地址 “凭证类型”选择“首次登录时设置”时必填,选择其他时选填。IAM用户绑定的邮件地址可作为IAM用户的登录凭证,也可由IAM用户自己绑定。 暂不配置 手机号 选填。IAM用户绑定的手机号,可作为IAM用户的登录凭证,也可由IAM用户自己绑定。 暂不配置 描述 选填。记录IAM用户相关信息。 暂不配置 图4 配置访问方式 表2 访问方式 访问方式 说明 取值样例 编程访问 为IAM用户启用访问密钥或密码,支持用户通过API、CLI、SDK等开发工具访问云服务。 勾选 管理控制台访问 为IAM用户启用密码,支持用户登录管理控制台访问云服务。此时凭证类型“密码”为必选项。 勾选 如果IAM用户仅需登录管理控制台访问云服务,建议访问方式选择管理控制台访问,凭证类型为密码。 如果IAM用户仅需编程访问华为云服务,建议访问方式选择编程访问,凭证类型为访问密钥。 如果IAM用户需要使用密码作为编程访问的凭证(部分API要求),建议访问方式选择编程访问,凭证类型为密码。 如果IAM用户使用部分云服务时,需要在其控制台验证访问密钥(由IAM用户输入),建议访问方式选择编程访问和管理控制台访问,凭证类型为密码和访问密钥。例如IAM用户在控制台使用 云数据迁移 CDM服务创建数据迁移,需要通过访问密钥进行身份验证。 表3 配置凭证类型和登录保护 凭证类型与登录保护 说明 取值样例 访问密钥 访问密钥(AK/SK,Access Key ID/Secret Access Key)包含访问密钥ID(AK)和秘密访问密钥(SK)两部分,是您在华为云的长期身份凭证,您可以通过访问密钥对华为云API的请求进行签名。 创建用户完成后即可下载本次创建的所有用户的访问密钥(AK/SK)访问密钥(AK/SK)。 不勾选 密码 自定义 自定义用户密码,并选择用户首次登录时是否需要重置密码。 如果您是用户的使用主体,建议您选择该方式,设置自己的登录密码,且无需勾选首次登录时重置密码。 选择 自动生成 系统自动生成IAM用户的登录密码,创建完用户即可下载excel形式的密码文件。将密码文件提供给用户,用户使用该密码登录。 仅在创建单个用户时适用。 - 首次登录时设置 系统通过邮件发一次性登录链接给用户,用户登录控制台并设置密码。 如果您不是用户的使用主体,建议选择该方式,同时输入用户的邮件地址和手机,用户通过邮件中的一次性链接登录华为云,自行设置密码。该链接7天内有效。 - 登录保护 开启登录保护 开启登录保护后,IAM用户登录时,除了在登录页面输入用户名和密码外(第一次身份验证),还需要在登录验证页面输入验证码(第二次身份验证)。 该功能是一种安全实践,您可以选择通过手机、邮件地址、虚拟MFA进行登录验证。 - 不开启 创建完成后,如需开启登录保护,请参见:登录保护。 选择 单击“下一步”,将IAM用户James、Alice加入到上一步中创建的“网络域运维”用户组。 如果该用户是管理员,可以将用户加入默认用户组“admin”中。 一个用户可以同时加入多个用户组。 单击“下一步”,IAM用户创建完成,用户列表中显示新创建的IAM用户James和Alice。如果3勾选了“凭证类型”中的“访问密钥”,可在此页面下载访问密钥。 图5 创建成功
  • IAM用户登录并验证权限 在登录页面,单击登录下方的“IAM用户”“IAM用户登录”“子用户登录”,在“IAM用户登录”页面,输入“租户名/原华为云账号名”、“IAM用户名/邮件地址”和“IAM用户密码”“账号名”、“用户名/邮箱”和“密码”。 图6 IAM用户登录 表4 登录信息 参数 示例 说明 租户名/原华为云账号名 Company-A IAM用户所属的账号。此处假设A公司的账号名为“Company-A”。 IAM用户名/邮件地址 Alice 在IAM创建用户时,输入的IAM用户名/邮件地址。如果不知道IAM用户名及初始密码,请向管理员获取。 IAM用户密码 ******** IAM用户的密码,非账号密码。此处需要输入上一步中下载的Alice用户的密码。 单击“登录”,登录华为云。 在“服务列表”中选择 云搜索 服务,进入云搜索服务CSS控制台。 在云搜索服务总览页面右上角,单击“创建集群”按钮,按照创建集群的步骤创建集群,如果创建成功,则表示权限配置成功。
  • 约束限制 删除集群时,会清理集群业务数据,请谨慎操作。 如果集群没有备份快照,则删除后不可恢复集群数据。当集群启用过快照功能,且OBS桶中创建的快照并未被删除,此时删除集群时,并不会释放这部分备份数据。如果有需要,可以通过OBS桶中存储的快照信息恢复数据,具体参见集群被删除后是否还能恢复?。 当集群已开通终端节点服务时,当前账号必须要有删除终端节点的权限,否则集群删除后并不会释放终端节点资源。终端节点的相关权限请参见VPCEP权限管理。
  • 配置自定义词库 登录云搜索服务管理控制台。 在左侧导航栏,选择对应的集群类型,进入集群列表页面。 在“集群管理”页面,单击需要配置自定义词库的集群名称,进入集群基本信息页面。 选择“自定义词库”。 在“自定义词库”页面,配置集群的自定义词库或修改预置词库。 当需要配置用户自定义的词库时,参考表1完成配置。 表1 配置自定义词库 参数 说明 OBS桶 选择词库文件存储的OBS位置。 单击“创建桶”可以跳转到创建桶页面新建OBS桶,新建OBS桶必须和集群在相同“区域”,且“默认存储类别”只支持“标准存储”或“低频访问存储”。 主词词库 主词词库是用户自定义的词库,初始状态为空。默认选择“不更新”表示不配置该词库。 当需要添加自定义的主词词库时,单击“更新”,选择txt格式的词库文件。 当无需添加自定义的主词词库时,单击“不使用此词库”,删除词库。 停词词库 停词词库是用户自定义的词库,初始状态为空。默认选择“不更新”表示不配置该词库。 当需要添加自定义的停词词库时,单击“更新”,选择txt格式的词库文件。 当无需添加自定义的停词词库时,单击“不使用此词库”,删除词库。 同义词词库 同义词词库是用户自定义的词库,初始状态为空。默认选择“不更新”表示不配置该词库。 当需要添加自定义的同义词词库时,单击“更新”,选择txt格式的词库文件。 当无需添加自定义的同义词词库时,单击“不使用此词库”,删除词库。 当需要修改预置词库时,单击打开“修改预置词库”右侧的开关,修改对应的预置词库。 如果界面不存在静态词库和Extra词库这4个词库时,表示该集群版本不支持删除或修改这4个预置词库。如果想要使用该功能,建议升级集群版本,或者新建集群并进行数据迁移。 表2 配置预置词库 参数 说明 静态主词词库 静态主词词库是预置的常用词语的主词库。默认选择“不更新”表示使用该预置词库。 当需要修改预置的静态主词词库时,单击“更新”,选择txt格式的词库文件。 当不使用静态主词库时,单击“不使用此词库”,删除词库。 静态停词词库 静态停词词库是预置的常用词语的停词库。默认选择“不更新”表示使用该预置词库。 当需要修改预置的静态停词词库时,单击“更新”,选择txt格式的词库文件。 当不使用静态停词库时,单击“不使用此词库”,删除词库。 Extra主词词库 Extra主词词库是预置的生僻词语的主词库。默认选择“不更新”表示使用该预置词库。 当需要修改预置的Extra主词词库时,单击“更新”,选择txt格式的词库文件。 当不使用Extra主词库时,单击“不使用此词库”,删除词库。 Extra停词词库 Extra停词词库是预置的生僻词语的Extra停词库。默认选择“不更新”表示使用该预置词库。 当需要修改预置的Extra停词词库时,单击“更新”,选择txt格式的词库文件。 当不使用Extra停词库时,单击“不使用此词库”,删除词库。 单击“保存”,在弹窗中单击“确定”。词库信息在下方呈现,此时词库状态为“更新中”。请耐心等待1分钟左右,当词库配置完成后,词库状态变更为“成功”。 当删除或更新静态词库和Extra词库这4个词库时,需要重启集群才能使配置的词库生效;其他词库的更新为动态更新,无需重启集群。重启集群的操作指导请参见重启Elasticsearch集群。
  • 配置简繁体转换搜索 登录云搜索服务管理控制台。 在左侧导航栏中,选择“集群管理”,进入集群列表页面。 在集群列表中,单击需要使用的集群对应“操作”列的“Kibana”。 如果开启了安全模式,需要输入创建集群时设置的管理员账户名和密码。 在Kibana的左侧导航中选择“Dev Tools”,进入Console界面。 在Console界面,执行如下命令,创建索引“stconvert”,并指定自定义映射来定义数据类型。 Elasticsearch低于7.x版本的代码示例 PUT /stconvert{ "settings": { "number_of_shards": 1, "number_of_replicas": 0, "analysis": { "analyzer": { "ts_ik": { "tokenizer": "ik_smart", "char_filter": [ "tsconvert", "stconvert" ] } }, "char_filter": { "tsconvert": { "type": "stconvert", "convert_type": "t2s" }, "stconvert": { "type": "stconvert", "convert_type": "s2t" } } } }, "mappings": { "type": { "properties": { "desc": { "type": "text", "analyzer": "ts_ik" } } } }} Elasticsearch大于或等于7.x版本和OpenSearch集群的代码示例 PUT /stconvert{ "settings": { "number_of_shards": 1, "number_of_replicas": 0, "analysis": { "analyzer": { "ts_ik": { "tokenizer": "ik_smart", "char_filter": [ "tsconvert", "stconvert" ] } }, "char_filter": { "tsconvert": { "type": "stconvert", "convert_type": "t2s" }, "stconvert": { "type": "stconvert", "convert_type": "s2t" } } } }, "mappings": { "properties": { "desc": { "type": "text", "analyzer": "ts_ik" } } }} 返回结果如下所示。 { "acknowledged" : true, "shards_acknowledged" : true, "index" : "stconvert"} 在Console界面,执行如下命令,导入数据到“stconvert”索引中。 Elasticsearch低于7.x版本的代码示例 POST /stconvert/type/1{ "desc": "國際電視臺"} Elasticsearch大于或等于7.x版本和OpenSearch集群的代码示例 POST /stconvert/_doc/1{ "desc": "國際電視臺"} 当返回结果信息中“failed”字段的值为“0”时,表示数据导入成功。 在Console界面,执行如下命令,搜索关键字“国际”,并查看搜索结果。 GET /stconvert/_search{ "query": { "match": { "desc": "国际" } }} 搜索结果如下所示。 { "took" : 15, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 1, "max_score" : 0.5753642, "hits" : [ { "_index" : "stconvert", "_type" : "type", "_id" : "1", "_score" : 0.5753642, "_source" : { "desc" : "國際電視臺" } } ] }}
  • 场景介绍 简繁体转换插件是一款可以使中文简体和中文繁体相互转换的插件。通过该插件的转换,用户可以使用中文繁体关键字搜索出包含对应中文简体的索引数据,也可以使用中文简体关键字搜索出包含对应中文繁体的索引数据。 云搜索服务默认安装了简繁体转换插件,用户无需自行安装。 简繁体转换插件通常可以当做analyzer、tokenizer、token-filter或char-filter来使用。 简繁体转换插件的转换类型包含如下两种: s2t:将中文简体转换为中文繁体。 t2s:将中文繁体转换为中文简体。
  • CSS自定义策略样例 如果系统预置的CSS权限,不满足您的授权要求,可以创建自定义策略。自定义策略中可以添加的授权项(Action)请参考权限策略和授权项。 目前华为云支持以下两种方式创建自定义策略: 可视化视图创建自定义策略:无需了解策略语法,按可视化视图导航栏选择云服务、操作、资源、条件等策略内容,可自动生成策略。 JSON视图创建自定义策略:可以在选择策略模板后,根据具体需求编辑策略内容;也可以直接在编辑框内编写JSON格式的策略内容。 具体创建步骤请参见:创建自定义策略。下面为您介绍常用的CSS自定义策略样例。 为了兼容开源生态,CSS服务的IAM权限和数据面集群权限分开控制,如果要开启数据面的安全能力,需要使用安全模式。 如果是子账号,需要同时设置GetBucketStoragePolicy、GetBucketLocation、ListBucket、ListAllMyBuckets权限,才能看到OBS桶。 示例1:授权用户创建集群。 { "Version": "1.1", "Statement": [ { "Action": [ "css:cluster:create", "vpc:securityGroups:get", "vpc:securityGroups:create", "vpc:securityGroups:delete", "vpc:securityGroupRules:get", "vpc:securityGroupRules:create", "vpc:securityGroupRules:delete", "vpc:vpcs:list", "vpc:privateIps:list", "vpc:ports:get", "vpc:ports:create", "vpc:ports:update", "vpc:ports:delete", "vpc:quotas:list", "vpc:subnets:get", "ecs:cloudServerFlavors:get", "ecs:serverInterfaces:use", "ecs:cloudServers:addNics", "ecs:quotas:get", "evs:types:get", "evs:quotas:get" ], "Effect": "Allow" } ]} 示例2:拒绝用户删除集群。 拒绝策略需要同时配合其他策略使用,否则没有实际作用。用户被授予的策略中,一个授权项的作用如果同时存在Allow和Deny,则遵循Deny优先原则。 如果您给用户授予CSS Admin的系统策略,但不希望用户拥有CSS admin中定义的删除云服务器权限,您可以创建一条拒绝删除云服务的自定义策略,然后同时将CSS Admin和拒绝策略授予用户,根据Deny优先原则,则用户可以对CSS执行除了删除集群外的所有操作。拒绝策略示例如下: { "Version": "1.1", "Statement": [ { "Effect": "Deny", "Action": [ "css:cluster:delete" ] } ] } 示例3:多个授权项策略。 一个自定义策略中可以包含多个授权项,且除了可以包含本服务的授权项外,还可以包含其他服务的授权项,可以包含的其他服务必须跟本服务同属性,即都是项目级服务或都是全局级服务。多个授权语句策略描述如下: { "Version": "1.1", "Statement": [ { "Action": [ "ecs:cloudServers:resize", "ecs:cloudServers:delete", "ecs:cloudServers:delete", "css:cluster:restart", "css:*:get*", "css:*:list*" ], "Effect": "Allow" } ]}
  • 代码示例 from elasticsearch import Elasticsearchfrom elasticsearch import helpers# 创建Elasticsearch客户端def get_client(hosts: list, user: str = None, password: str = None): if user and password: return Elasticsearch(hosts, http_auth=(user, password), verify_certs=False, ssl_show_warn=False) else: return Elasticsearch(hosts)# 创建索引表def create(client: Elasticsearch, index: str): # 索引mapping信息 index_mapping = { "settings": { "index": { "vector": "true", # 开启向量特性 "number_of_shards": 1, # 索引分片数,根据实际需求设置 "number_of_replicas": 0, # 索引副本数,根据实际需求设置 } }, "mappings": { "properties": { "my_vector": { "type": "vector", "dimension": 2, "indexing": True, "algorithm": "GRAPH", "metric": "euclidean" } # 可根据需求添加其他字段 } } } res = client.indices.create(index=index, body=index_mapping) print("create index result: ", res)# 写入数据def write(client: Elasticsearch, index: str, vecs: list, bulk_size=500): for i in range(0, len(vecs), bulk_size): actions = [ { "_index": index, "my_vector": vec, # 可根据需求添加其他字段 } for vec in vecs[i: i+bulk_size] ] success, errors = helpers.bulk(client, actions, request_timeout=3600) if errors: print("write bulk failed with errors: ", errors) # 根据需求进行错误处理 else: print("write bulk {} docs success".format(success)) client.indices.refresh(index=index, request_timeout=3600)# 查询向量索引def search(client: Elasticsearch, index: str, query: list, size: int): # 查询语句,可根据需求选择合适的查询方式 query_body = { "size": size, "query": { "vector": { "my_vector": { "vector": query, "topk": size } } } } res = client.search(index=index, body=query_body) print("search index result: ", res)# 删除索引def delete(client: Elasticsearch, index: str): res = client.indices.delete(index=index) print("delete index result: ", res)if __name__ == '__main__': # 对于非安全集群,使用: es_client = get_client(hosts=['http://x.x.x.x:9200']) # 对于开启了https的安全集群,使用: # es_client = get_client(hosts=['https://x.x.x.x:9200', 'https://x.x.x.x:9200'], user='xxxxx', password='xxxxx') # 对于未开启https的安全集群,使用: # es_client = get_client(hosts=['http://x.x.x.x:9200', 'http://x.x.x.x:9200'], user='xxxxx', password='xxxxx') # 测试索引名称 index_name = "my_index" # 创建索引 create(es_client, index=index_name) # 写入数据 data = [[1.0, 1.0], [2.0, 2.0], [3.0, 3.0]] write(es_client, index=index_name, vecs=data) # 查询索引 query_vector = [1.0, 1.0] search(es_client, index=index_name, query=query_vector, size=3) # 删除索引 delete(es_client, index=index_name)
  • 示例流程 图1 给用户授权CSS权限流程 创建用户组并授权 在IAM控制台创建用户组,并授予云搜索服务只读权限“CSS ReadOnlyAccess”。 创建用户并加入用户组 在IAM控制台创建用户,并将其加入1中创建的用户组。 将用户添加至用户组中,从而使用户拥有对应的CSS权限,一个用户组下面的用户具有相同的权限。 用户登录并验证权限 新创建的用户登录控制台,切换至授权区域,验证权限: 在“服务列表”中选择云搜索服务CSS,进入CSS主界面,单击右上角“创建集群”,尝试购买CSS集群,如果无法购买CSS集群(假设当前权限仅包含CSS ReadOnlyAccess),表示“CSS ReadOnlyAccess”已生效。 在“服务列表”中选择除云搜索服务外(假设当前策略仅包含CSS ReadOnlyAccess)的任一服务,如果提示权限不足,表示“CSS ReadOnlyAccess”已生效。
  • 修改企业项目 针对之前已创建的集群,其绑定的企业项目可根据实际情况进行修改。 登录在云搜索服务管理控制台, 在左侧导航栏,选择对应的集群类型,进入集群管理页面。 在集群列表中,单击集群名称进入集群“基本信息”页面。 在集群“基本信息”页面,单击“企业项目”右侧的企业项目名称,进入项目管理页面。 在“资源”页签下,“区域”选项中选择当前集群所在的区域,“服务”选项中选“云搜索服务 CSS”。此时,资源列表将筛选出对应的CSS集群。 图1 筛选CSS集群 勾选需要修改企业项目的集群,然后单击“迁出”。 在“迁出资源”页面,选择“迁出方式”,再选择“请选择要迁入的企业项目”,然后单击“确定”。 迁出完成后,可以在云搜索服务管理控制台集群管理页面,查看修改后的集群企业项目信息。
  • 使用Spring Boot接入HTTPS集群(使用安全证书) 该场景适用于使用安全证书连接安全模式+HTTPS协议的集群。 获取安全证书(CloudSearchService.cer)。 登录云搜索服务控制台。 选择“集群管理”进入集群列表。 单击对应集群的名称,进入集群基本信息页面。 在“基本信息”页面,单击“HTTPS访问”后面的“下载证书”。 图1 下载证书 转换安全证书(CloudSearchService.cer)。将下载的安全证书上传到客户端机器上,使用keytool工具将“.cer”证书转换成Java可以读取的“.jks”证书格式。 在Linux系统中,执行如下命令转换证书。 keytool -import -alias newname -keystore ./truststore.jks -file ./CloudSearchService.cer 在Windows系统中,执行如下命令转换证书。 keytool -import -alias newname -keystore .\truststore.jks -file .\CloudSearchService.cer 其中,newname是由用户自定义的证书名称。 该命令执行后,会提示设置证书密码,并确认密码。请保存该密码,后续接入集群会使用。 application.properties配置文件: 123 elasticsearch.url=host1:9200,host2:9200elasticsearch.username=usernameelasticsearch.password=password 表3 参数说明 参数 描述 host Elasticsearch集群的访问地址。 username 访问集群的用户名。 password 用户名对应的密码。 配置代码: com.xxx为项目目录,例如com.company.project。 com.xxx.repository为仓库目录,通过extends org.springframework.data.elasticsearch.repository.ElasticsearchRepository进行具体定义。 1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 package com.xxx.configuration;import org.elasticsearch.client.RestHighLevelClient;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.data.elasticsearch.client.ClientConfiguration;import org.springframework.data.elasticsearch.client.RestClients;import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;import java.io.File;import java.io.FileInputStream;import java.io.InputStream;import java.security.KeyStore;import java.security.SecureRandom;import java.security.cert.CertificateException;import java.security.cert.X509Certificate;import javax.net.ssl.HostnameVerifier;import javax.net.ssl.SSLContext;import javax.net.ssl.SSLSession;import javax.net.ssl.TrustManager;import javax.net.ssl.TrustManagerFactory;import javax.net.ssl.X509TrustManager;@Configuration@EnableElasticsearchRepositories(basePackages = "com.xxx.repository")@ComponentScan(basePackages = "com.xxx")public class Config extends AbstractElasticsearchConfiguration { @Value("${elasticsearch.url}") public String elasticsearchUrl; @Value("${elasticsearch.username}") public String elasticsearchUsername; @Value("${elasticsearch.password}") public String elasticsearchPassword; @Override @Bean public RestHighLevelClient elasticsearchClient() { SSLContext sc = null; try { TrustManager[] tm = {new MyX509TrustManager(cerFilePath, cerPassword)}; sc = SSLContext.getInstance("SSL", "SunJSSE"); sc.init(null, tm, new SecureRandom()); } catch (Exception e) { e.printStackTrace(); } final ClientConfiguration clientConfiguration = ClientConfiguration.builder() .connectedTo(StringHostParse(elasticsearchUrl)) .usingSsl(sc, new NullHostNameVerifier()) .withBasicAuth(elasticsearchUsername, elasticsearchPassword) .build(); return RestClients.create(clientConfiguration).rest(); } private String[] StringHostParse(String hostAndPorts) { return hostAndPorts.split(","); } public static class MyX509TrustManager implements X509TrustManager { X509TrustManager sunJSSEX509TrustManager; MyX509TrustManager(String cerFilePath, String cerPassword) throws Exception { File file = new File(cerFilePath); if (!file.isFile()) { throw new Exception("Wrong Certification Path"); } System.out.println("Loading KeyStore " + file + "..."); InputStream in = new FileInputStream(file); KeyStore ks = KeyStore.getInstance("JKS"); ks.load(in, cerPassword.toCharArray()); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509", "SunJSSE"); tmf.init(ks); TrustManager[] tms = tmf.getTrustManagers(); for (TrustManager tm : tms) { if (tm instanceof X509TrustManager) { sunJSSEX509TrustManager = (X509TrustManager) tm; return; } } throw new Exception("Couldn't initialize"); } @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } } public static class NullHostNameVerifier implements HostnameVerifier { @Override public boolean verify(String arg0, SSLSession arg1) { return true; } }} 其中,cerFilePath和cerPassword是生成的.jks证书的存放路径及其密码。
  • 注意事项 建议Elasticsearch Rest High Level Client的版本和Elasticsearch的版本保持一致,例如需要访问的Elasticsearch集群版本是7.10.2,则使用的Elasticsearch Rest High Level Client客户端版本建议也是7.10.2。 本章节以2.5.5版本Spring Boot为例介绍Spring Boot接入集群的方式,对应的spring data elasticsearch版本是4.2.x。
  • 使用Spring Boot接入HTTPS集群(不使用安全证书) 该场景适用于不使用安全证书连接安全模式+HTTPS协议的集群。 配置文件: 123 elasticsearch.url=host1:9200,host2:9200elasticsearch.username=usernameelasticsearch.password=password 表2 参数说明 参数 描述 host Elasticsearch集群的访问地址。 username 访问集群的用户名。 password 用户名对应的密码。 配置代码: com.xxx为项目目录,例如com.company.project。 com.xxx.repository为仓库目录,通过extends org.springframework.data.elasticsearch.repository.ElasticsearchRepository进行具体定义。 1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 package com.xxx.configuration;import org.elasticsearch.client.RestHighLevelClient;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.data.elasticsearch.client.ClientConfiguration;import org.springframework.data.elasticsearch.client.RestClients;import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;import java.security.KeyManagementException;import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;import java.security.cert.CertificateException;import java.security.cert.X509Certificate;import javax.net.ssl.HostnameVerifier;import javax.net.ssl.SSLContext;import javax.net.ssl.SSLSession;import javax.net.ssl.TrustManager;import javax.net.ssl.X509TrustManager;@Configuration@EnableElasticsearchRepositories(basePackages = "com.xxx.repository")@ComponentScan(basePackages = "com.xxx")public class Config extends AbstractElasticsearchConfiguration { @Value("${elasticsearch.url}") public String elasticsearchUrl; @Value("${elasticsearch.username}") public String elasticsearchUsername; @Value("${elasticsearch.password}") public String elasticsearchPassword; @Override @Bean public RestHighLevelClient elasticsearchClient() { SSLContext sc = null; try { sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new SecureRandom()); } catch (KeyManagementException | NoSuchAlgorithmException e) { e.printStackTrace(); } final ClientConfiguration clientConfiguration = ClientConfiguration.builder() .connectedTo(StringHostParse(elasticsearchUrl)) .usingSsl(sc, new NullHostNameVerifier()) .withBasicAuth(elasticsearchUsername, elasticsearchPassword) .build(); return RestClients.create(clientConfiguration).rest(); } private String[] StringHostParse(String hostAndPorts) { return hostAndPorts.split(","); } public static TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } } }; public static class NullHostNameVerifier implements HostnameVerifier { @Override public boolean verify(String arg0, SSLSession arg1) { return true; } }}
  • 通过Spring Boot接入HTTP集群 该场景适用于连接非安全模式的集群或是安全模式+HTTP协议的集群。 配置文件: 1234 elasticsearch.url=host1:9200,host2:9200//非安全集群不用配置如下两行。elasticsearch.username=usernameelasticsearch.password=password 表1 参数说明 参数 描述 host Elasticsearch集群的访问地址。 username 访问集群的用户名。 password 用户名对应的密码。 配置代码: com.xxx为项目目录,例如com.company.project。 com.xxx.repository为仓库目录,通过extends org.springframework.data.elasticsearch.repository.ElasticsearchRepository进行具体定义。 1 2 3 4 5 6 7 8 910111213141516171819202122232425262728293031323334353637383940414243 package com.xxx.configuration;import org.elasticsearch.client.RestHighLevelClient;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.data.elasticsearch.client.ClientConfiguration;import org.springframework.data.elasticsearch.client.RestClients;import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;@Configuration@EnableElasticsearchRepositories(basePackages = "com.xxx.repository")@ComponentScan(basePackages = "com.xxx")public class Config extends AbstractElasticsearchConfiguration { @Value("${elasticsearch.url}") public String elasticsearchUrl; //非安全集群不用配置如下两个参数。 @Value("${elasticsearch.username}") public String elasticsearchUsername; @Value("${elasticsearch.password}") public String elasticsearchPassword; @Override @Bean public RestHighLevelClient elasticsearchClient() { final ClientConfiguration clientConfiguration = ClientConfiguration.builder() .connectedTo(StringHostParse(elasticsearchUrl)) //非安全集群无需配置withBasicAuth。 .withBasicAuth(elasticsearchUsername, elasticsearchPassword) .build(); return RestClients.create(clientConfiguration).rest(); } private String[] StringHostParse(String hostAndPorts) { return hostAndPorts.split(","); }}
  • 审计与日志 云审计 服务(Cloud Trace Service, CTS ),是华为 云安全 解决方案中专业的日志审计服务,提供对各种云资源操作记录的收集、存储和查询功能,可用于支撑安全分析、合规审计、资源跟踪和问题定位等常见应用场景。 用户开通云审计服务后,CTS可记录NAT网关的操作事件用于审计。 CTS的详细介绍和开通配置方法,请参见CTS快速入门。 NAT网关支持审计的操作事件请参见支持审计的关键操作。 查看审计日志请参见查看审计日志。 父主题: 安全
  • 责任共担 华为云秉承“将公司对网络和业务安全性保障的责任置于公司的商业利益之上”。针对层出不穷的云安全挑战和无孔不入的云安全威胁与攻击,华为云在遵从法律法规业界标准的基础上,以安全生态圈为护城河,依托华为独有的软硬件优势,构建面向不同区域和行业的完善云服务安全保障体系。 安全性是华为云与您的共同责任,如图1所示。 华为云:负责云服务自身的安全,提供安全的云。华为云的安全责任在于保障其所提供的IaaS、PaaS和SaaS类云服务自身的安全,涵盖华为云数据中心的物理环境设施和运行其上的基础服务、平台服务、应用服务等。这不仅包括华为云基础设施和各项云服务技术的安全功能和性能本身,也包括运维运营安全,以及更广义的安全合规遵从。 租户:负责云服务内部的安全,安全地使用云。华为云租户的安全责任在于对使用的IaaS、PaaS和SaaS类云服务内部的安全以及对租户定制配置进行安全有效的管理,包括但不限于虚拟网络、 虚拟主机 和访客虚拟机的操作系统,虚拟防火墙、API网关和高级安全服务,各项云服务,租户数据,以及身份账号和密钥管理等方面的安全配置。 《华为云安全白皮书》详细介绍华为云安全性的构建思路与措施,包括云安全战略、责任共担模型、合规与隐私、安全组织与人员、基础设施安全、租户服务与租户安全、工程安全、运维运营安全、生态安全。 图1 华为云安全责任共担模型 父主题: 安全
  • 入门实践 当您完成了日志组、日志流等基本操作后,可以根据自身的业务需求使用 云日志 服务提供的一系列常用实践。 表1 常用最佳实践 实践 描述 对华为云ELB日志进行分析 该解决方案介绍将ELB日志接入LTS后,配置日志结构化后,即可进行日志搜索分析。 通过仪表盘可视化分析ELB日志 该解决方案介绍当ELB日志接入云日志服务后,您可以通过SQL语句查询分析日志,将日志结果保存为多种图表,并将图表保存至仪表盘,从而使用仪表盘实时分析ELB日志数据。您可以参考如下内容,进行具体的操作配置。 无服务器日志实时分析 该解决方案帮助您无服务器架构实现弹性云服务器 ECS日志的采集、分析、告警以及存档,基于云日志服务 LTS实时采集弹性云服务器 ECS的日志数据,通过 函数工作流 FunctionGraph的LTS触发器自动获取日志数据,并实现对日志中告警信息的分析,通过 消息通知 服务 SMN 将告警信息推送给用户,并存储到 对象存储服务 OBS桶中进行存档。 无服务器日志文件上传LTS 该解决方案可以帮助用户无服务器架构实现日志文件上传至云日志服务 LTS。日志文件压缩上传到对象存储服务 OBS,通过函数工作流的OBS 触发器获取日志文件压缩包,并实现自动解压、解析日志文件,将日志结果逐行存储到云日志服务 LTS。适用于将业务系统日志上传至云日志服务 LTS进行管理的场景。
  • 原因分析 RDS for MySQL 5.6实例建表时索引使用建议如下: 如果是单字段索引,则字段长度不应超过767字节。 如果是联合索引,则每个字段长度都不应超过767字节,且所有字段长度合计不应超过3072字节。 建表时使用utf8mb4字符集,这是一个4字节字符集。 当索引最大限制是767字节时,那么一个varchar字段长度:767/4=191.75。如果建表语句中varchar字段超出了这个长度,就会出现767字节长度报错。
  • 解决方案 pt-osc工具加上“--recursion-method=none”配置项,忽略复制延迟,即可解决问题。 pt-osc常见命令参考: 增加字段 pt-online-schema-change --user=root --password=xxx --host=xxx --alter “ADD COLUMN content text” D=aaa,t=tmp_test --no-check-replication-filters --alter-foreign-keys-method=auto --recursion-method=none --print --execute 删除字段 pt-online-schema-change --user=root --password=xxx --host=xxx --alter "DROP COLUMN content " D=aaa,t=tmp_test --no-check-replication-filters --alter-foreign-keys-method=auto --recursion-method=none --quiet --execute 修改字段 pt-online-schema-change --user=root --password=xxx --host=xxx --alter “MODIFY COLUMN age TINYINT NOT NULL DEFAULT 0” D=aaa,t=tmp_test --no-check-replication-filters --alter-foreign-keys-method=auto --recursion-method=none --quiet --execute 字段改名 pt-online-schema-change --user=root --password=xxx --host=xxx --alter “CHANGE COLUMN age address varchar(30)” D=aaa,t=tmp_test --no-check-alter --no-check-replication-filters --alter-foreign-keys-method=auto --recursion-method=none --quiet --execute 增加索引 pt-online-schema-change --user=root --password=xxx --host=xxx --alter “ADD INDEX idx_address(address)” D=aaa,t=tmp_test --no-check-alter --no-check-replication-filters --alter-foreign-keys-method=auto --recursion-method=none --print --execute 删除索引 pt-online-schema-change --user=root --password=xxx --host=xxx --alter “DROP INDEX idx_address” D=aaa,t=tmp_test --no-check-alter --no-check-replication-filters --alter-foreign-keys-method=auto --recursion-method=none --print --execute 如果业务需要关注复制延迟,可以根据业务需要调整如下参数:max-lag、check-interval、recursion-method、check-slave-lag。更多信息,请参见pt-osc官方文档。
  • 原因分析 pt-osc的工作原理: 创建一个与原表结构相同的空表,表名是 _new 后缀。 修改1创建的空表的表结构。 在原表上加三个触发器:delete/update/insert,用于复制数据过程中,将原表中要执行的语句在新表中执行。 将原表数据以数据块(chunk)的形式复制到新表。 rename原表为旧表,并把新表rename为原表名,然后删除旧表。 删除触发器。 因为涉及大量数据复制,对于有从库的MySQL,必然会带来主备复制延迟,可能影响从库业务。考虑从库延迟情况,pt-osc工具提供以下几个控制选项: --max-lag --check-interval --recursion-method --check-slave-lag 因此,从库延迟超过max-lag,则停止复制数据,等待check-interval秒后再开始复制数据;check-slave-lag指定slave的机器,只会对比这台slave的延迟情况。recursion-method是主库寻找从库的方法:processlist(默认值,关注从库延迟)、hosts、dsn、none(忽略从库延迟)。更多信息,请参见pt-osc官方文档。 本案例场景中: pt-osc工具连接云上RDS for MySQL主备实例卡住,是因为存在主从复制延迟导致工具停止复制数据。配置项“--recursion-method=none”表示忽略主从延迟,添加该配置项可以解决问题。 忽略主从延迟,会导致复制数据比较快,当需要尽可能的对服务产生小的影响,可以设置“--max-load”配置项。
  • 场景描述 PostgreSQL官方标准语法里面创建索引时索引名不能包含schema名,例如“CREATE UNIQUE INDEX fee_code_desc_uni_idx”是正确的,如果增加了schema名,例如“CREATE UNIQUE INDEX "isp-1".fee_code_desc_uni_idx”就会报语法解析错误。 但是在华为云RDS for PostgreSQL 11创建索引时索引名可以包含schema名,华为云RDS for PostgreSQL 12创建索引时索引名不支持包含schema名。
  • 解决方案 使用rdsuser账号手动授予新账号的msdb库的public权限。具体操作如下: 方式一: 使用S SMS 工具,以rdsuser账号登录实例。 在新账号(newlogin)上右键单击,查看属性。 在“User Mapping”中勾选msdb库,查看下面勾选了public角色,单击“OK”。 图3 授予public权限 再次尝试使用新账号(newlogin)登录实例,则不会出现报错。 方式二: 使用DAS,以rdsuser账号登录实例。 执行以下SQL授予msdb库权限。SQL中待授权账号以newlogin为例。 USE [msdb] GO CREATE USER [newlogin] FOR LOG IN [newlogin] GO 再次尝试使用新账号(newlogin)登录实例,则不会出现报错。
  • 场景一 场景描述 使用RDS for PostgreSQL数据库时,业务执行大量复杂SQL,造成临时文件堆积,内存耗尽发生OOM,数据库重启过程非常缓慢,导致业务较长时间不可用。 原因分析 由于业务执行复杂SQL,如果SQL中涉及排序、Hash join、聚合等操作,超过配置work_mem参数大小时,会生成临时文件。大量执行这样的SQL,在发生OOM时,数据库进程被OS杀掉,此时内核不会对临时文件进行清理,从而导致临时文件的堆积。过多的临时文件会拖慢数据库启动,这是因为在PostgreSQL数据库进程启动时,需要删除所有之前产生的所有临时文件,如果存在大量临时文件堆积,将导致数据库启动缓慢。 解决方案 建议业务侧优化SQL,或适当调大work_mem参数值(会增加内存占用),减少临时文件生成。
  • 场景二 场景描述 使用RDS for PostgreSQL数据库时,业务创建了大量的表。某一时间连接数与业务量激增,数据库进程内存耗尽发生OOM,从而导致数据库重启,但重启过程非常缓慢,导致业务较长时间不可用。 原因分析 由于数据库发生了OOM进而导致进程重启,在启动时会进入故障恢复模式,这时内核进程会遍历所有表并做fsync(将os缓存内容刷新至磁盘),如果业务创建的表对象过多,在启动时便会消耗大量时间进行遍历,从而导致数据库启动缓慢,影响业务可用性。 解决方案 建议业务侧限制创建表的数量,单实例表数量最好不超过2万,单库表数量最好不超过4千,详见实例使用规范。 建议业务侧配置内存监控,必要时扩充内存规格,尽量避免OOM发生。同时关注inode数监控指标,控制创建的对象数量。
共100000条
提示

您即将访问非华为云网站,请注意账号财产安全