phython在file同时写入两个_轻松支撑百万级数据点写入 京东智联云时序数据库HoraeDB架构解密...

本文将通过对时序数据的基本概念、应用场景以及京东智联云时序数据库HoraeDB的介绍,为大家揭秘HoraeDB的核心技术架构和解决方案。

ed78c20165f35df700a2b5363e469231.png

首先我们来了解下时序数据库的基本概念。时序数据库全称时间序列数据库,主要用于处理带时间标签的数据,带时间标签的数据也称为时序数据。

时序数据库是一种高性能、低成本、稳定可靠的在线时序时空数据库服务,提供高效读写、高压缩比存储、时序数据插值及聚合计算等服务,广泛应用于服务和服务器监控系统、物联网(IoT)设备监控系统、生产安全监控系统和电力检测系统等行业场景。此外,它还能提供时空场景的查询和分析能力。

时序数据库中存储的是时序数据,时序数据的结构特点和简单举例如下:

728255e51b32a76e89a0d7f3d9ea0377.png

上图展示的是一个服务和时间点紧密关联的流量变化数据,数据如下:

702b14e11fb3b7684beb33027ce51fbd.png
  • Metric:时序数据的指标名称;
  • Tags:对时序数据指标进行补充描述的标签,描述清楚数据是什么、来源等,方便后期对数据进行筛选和聚合计算等;
  • Dps:时序数据的数据点,是一系列随着时间变化的值,分为时间戳和具体的value两个部分。

b962960b2cfbd07a99e66f43ec5bdb3a.png
  • 证券交易:可以用时序数据库来保存随着时间波动的交易价格等数据;
  • 气温变化情况:可以用时序数据库存储气温变化的数据,便于记录和分析某个地区的气温变化波动规律;
  • 服务器监控:通过对大规模应用集群和机房设备的数据采集,存储到时序数据库中,就可以实时关注设备运行状态、资源利用率和业务趋势,实现数据化运营和自动化开发运维;
  • 物联网传感器:物联网设备无时无刻不在产生海量的设备状态数据和业务消息数据,这些数据有助于进行设备监控、业务分析预测和故障诊断;
  • 网站/服务监控数据:通过日志或者其他方式对原始指标数据进行采集和实时计算,最后将实时计算的结果数据存储到时序数据库,实现对网站和服务的监控和分析。

aec163b2a4dee4da6297faaafdd018d4.png
  • 时序数据的写入:每秒需要有百万至千万量级的时序数据点写入,并且写入流量没有低峰期和高峰期的区分,所以时序数据库需要解决好如何7*24小时支持好百万甚至上千万级的时序数据写入问题;
  • 时序数据的读取:如何低延迟解决好单个请求读取百万级数据点的查询以及几十万级别数据计算和聚合问题;
  • 成本问题:时序数据数据量级较大,且在业务上可能至少需要存储一年以上的历史数据,以便于后期来对数据进行分析和处理,所以时序数据库需要解决好存储成本的问题。

0c9a7ae1a3f4cdfc7ae02f048e0d1821.png

HoraeDB是京东智联云自研的一款时序数据库,在数据的写入协议上完全兼容OpenTSDB,数据的查询上兼容OpenTSDB restful API和PromQL。

HoraeDB主要有以下特点:

  • 高性能:支持数据批量异步写入,高并发查询以及强大的数据计算和聚合能力;
  • 高可用:数据存储分布式架构,副本数和数据的一致性级别灵活可调;可以根据需要,对数据的写入做多AZ双写和HA查询等;
  • 使用成本低:丰富的数据类型,REST接口、数据写入查询均使用json格式,并且接口和协议上完全兼容OpenTSDB和PromQL,历史服务前移学习成本较低;
  • 兼容开源生态:兼容OpenTSDB和PromQL协议以及开源的Kibana组件,可以方便的使用开源生态中已存在的工具和组件对时序数据进行查询、分析和展示等。

0c9a7ae1a3f4cdfc7ae02f048e0d1821.png

58afea942b56b6b2798ad5ccf3984c47.png

HoraeDB在整体架构上从上往下进行分层,大概可以分为以下几层:

  • Http-Server层:主要负责HTTP服务端口的监听、接收以及响应用户的请求;
  • 协议处理层:这层是负责对接各种已有的开源组件的协议。主要是包括OpenTSDB-Parser、Prometheus-Adapter、Remote-Read、Remote-Write等几个组件:
    ◆OpenTSDB-Parser:负责对当前开源的OpenTSDB的请求协议进行解析和处理,包括查询请求和响应请求;
    ◆ Prometheus-Adapter:对PromQL查询语法进行解析,解析成HoraeDB内部标准的查询协议;
    ◆ Remote-Read:实现Prometheus的Remote-Read模式,可以使用Prometheus来查询HoraeDB中的数据,具体配置使用方式可以参考Prometheus配置说明;
    ◆ Remote-Writer:实现Prometheus的Remote-Write模式,可以在生产环境中将HoraeDB作为Prometheus的分布式集群存储解决方案,将Prometheus中采集到的数据写入到HoraeDB。具体配置使用方式可以参考Prometheus配置说明。
  • HoraeDB协议层:包括HoraeDB-PutReq和HoraeDB-QueryReq,这一层主要是定义好HoraeDB自身写入的数据的结构和查询请求的结构;
  • 处理引擎层:包括了write-engine和query-engine,这层是分别进行数据写入和查询的处理逻辑;
  • 数据队列:这一层主要是针对数据写入而言的,数据要写入到底层存储,会先写到队列中,然后消费端根据配置文件的指定的后端,进行数据的处理;
  • 存储Client层:适配各种各样的三方存储组件,负责数据的持久化存储处理,目前实现了ES-Client、Cassandra-Client、Cache-Client、Local-Storage:
    ◆ ES-Client:负责将时序数据中的Meta部分信息写入到ES进行存储;
    ◆ Cassandra-Client:负责将时序数据中的数据点写入到Cassandra中进行持久化存储;
    ◆ Cache-Client:将新写入的热点时序数据写入到高速缓存组件,对热点数据进行Cache。
  • 数据存储层
    ◆ Cassandra:存储时序数据中的数据点;
    ◆ ES:存储时序数据中的Meta信息;
    ◆ TS-Cache:自研的时序数据Cache系统,内部使用delta-delta和XOR编码方式对时序数据的时间戳和值进行压缩,可以存储最近三小时的热点时序数据。

166ae83ad51035287ce53b7284d6ae33.png

e211e3394fcec1d7677d8cd5c480361a.png

HoraeDB在底层数据存储将时序数据拆分成两部分进行存储,一部分是meta数据,这部分数据主要是对时序数据进行描述的,描述了一条时间序列是什么,来自于哪里;另外一部分是时序数据点,包括时间戳和具体的值,这部分数据是会随着时间变化,周期性上报的部分。例如下面一条数据:

17ee7788b410646e142d8f426fd9220a.png
  • Meta部分包括了name、tags、additionTag等三个部分,对一条时间线进行了描述;
  • 数据点部分包括了timeStamp和value,是具体的时序数据点。

它们各自的特点如下:

  • Meta
    ◆ 写入后,基本不会有变更;
    ◆ 需要支持多维度,多种方式进行数据筛选,比如Tag精确匹配,前缀搜索、正则匹配等多种搜索;
    ◆ 数据量相对小。
  • 时序数据点
    ◆ 周期性汇报;
    ◆ 和时间戳强关联;
    ◆ 需要支持按照时间范围进行数据筛选;
    ◆ 数据量大。

根据以上特点,我们在数据持久化存储中,针对Meta和时序数据点,分别选择了Elasticsearch和Cassandra来进行数据存储。

Elasticsearch

Elasticsearch是一个基于RESTful web接口并且构建在Apache Lucene之上的开源分布式搜索引擎。

同时ES还是一个分布式文档数据库,其中每个字段均可被索引,而且每个字段的数据均可被搜索,能够横向扩展至数以百计的服务器存储以及处理PB级的数据。可以在极短的时间内存储、搜索和分析大量的数据。

Cassandra

Cassandra是一套开源分布式NoSQL数据库系统。具有以下特点:

  • 线性扩展,轻松应对速度、多样性和复杂性问题:Cassandra是线性扩展,可以根据前台数据流量轻松确定集群规模;
  • 架构简单,运维成本低:Cassandra不依赖外部组件,所有必须的操作都集成在Cassandra内部了。同时,由于它是P2P对等架构,无主,环上的节点都是对等的,极度简化部署及后续运维工作,适合大规模部署;
  • 高可用:Cassandra采用了许多容错机制。由于Cassandra是无主的,所以没有单点故障,可以做到不停服滚动升级。这是因为Cassandra可以支持多个节点的临时失效(取决于群集大小),对集群的整体性能影响可以忽略不计。Cassandra提供多地域容灾,允许您将数据复制到其他数据中心,并在多个地域保留多副本。

HoraeDB在Cassandra中的Schema定义:

0b92f71bcc80c96b7ed3b3b8e5bba6db.png
  • 行定位:uuid + partitionKey来唯一定位到一行数据,uuid是根据name + 排序后的Tag来计算出来的,唯一可以表示单个时间序列的ID, partitionKey是由程序来定义的划分行的字符串,比如按照天来划分行,那么我们就可以传入数据时间戳的当天日期;
  • 列定位:每列由数据的时间戳来表示,每个时序点占一列,每列中包含value和createTime字段。value是经过编码后的数据,createTime是由时序数据点到来的时间计算出的timeUUID来表示,用于支持多版本的特性。

b8fd0ba425b758fe0c294a2c1047ce75.png

业务对于监控数据的使用需求多种多样,有查最新数据的异常告警,也有查看一整年指标数据的趋势图展示,数据量越大查询耗时就越久,如果放在浏览器端处理也要耗费大量的内存。这不但对系统造成了很大的压力,也给用户带来了难以忍受的查询体验。鉴于此,我们引入了多级的降采样机制来应对不同跨度的数据查询。

ed1f1d8ded35f2c47941b3a0c76bed7b.png

如上图所示,提前降低采样算法就是将连续不断流入的时序数据点来进行分桶,计算出这个桶内的均值、最大值、最小值、总和等,这样用户在查询数据的时候,直接返回合适的采样数据即可。

为了提供多种粒度的数据,HoraeDB支持对原始数据进行多级降采样,比如可以将原始数据降采样成10m和1h粒度的数据。

96dcc3cd3e185559ae6ecadf2c5de972.png

流式抽样的核心处理思想如上图所示:在HoraeDB的内存中保存了每个时间序列。每个序列上都维护了当前这个序列的cnt、sum、max、min、last等值,随着时间的推移,时序数据点源源不断的流入,相应序列上的cnt、sum、max、last都会进行累加或者值更新,当到达设定的时间窗口,比如10分钟,就会将计算后的结果存入到Cassandra中。

流式抽样中需要解决的难点主要有两个:数据迟到问题和时间窗口到达后对底层Cassandra的压力冲击。HoraeDB对这些问题的解决方案如下:

  • 数据迟到问题:为了解决数据迟到问题,HoraeDB的数据抽样器对每个时间序列的抽样结果暂存一个周期,等待迟到的数据到来,然后再存入到底层Cassandra;
  • 时间窗口到达,对底层尖峰流量:数据发送使用了令牌桶算法来进行数据的发送,控制数据发送频率。

06121af71510d86434191b2f8dac1f39.png

在时序的场景下,我们经常会有一些大批量数据分析计算的需求。比如需要计算10万个服务器30分钟内的cpu变化趋势。这样的查询会很慢,同时也会导致我们的时序存储服务不稳定。

为了应该对这种业务场景,我们做了预聚合计算方案,预聚合计算分为流式聚合计算和批量计算。如下图所示:

2edff6327ab490edceec59468f71d998.png
  • 流式聚合计算
    对于大规模时序数据分析场景,我们采用流式聚合计算,如上图所示,数据上报到kafka。我们的Flink Job会根据用户提前配置好的聚合规则,对流入的数据进行聚合计算,计算完成后,写回到我们的存储中,流式聚合计算有以下的特点:
    ◆ 计算性能强,可横向扩展;
    ◆ 计算支持灵活性相对较弱;
    ◆ 需要部署单独的计算等组件。
  • 批量聚合计算
    批量聚合计算使用的是拉模式进行数据聚合计算,核心逻辑是HoraeDB根据用户创建的聚合规则,设置一些定时计算任务,计算任务会定时向底层存储层发起数据拉取和计算,计算结果写回到存储中,批量聚合计算有以下的特点:
    ◆ 计算灵活性强;
    ◆ 无需单独部署计算组件和消息队列;
    ◆ 支持到5w线左右,对底层存储开销高。

e7f1748f0495124c6889a5a2eff2ec6f.png

444d48d071a11a01c846beb770cbd324.png

HoraeDB原有架构下,做一些大批量数据查询和计算时存在以下问题:

  • 聚合性能低:原有引擎在执行聚合运算的时候,也和传统数据库所通常采用的iterative执行模式一样,迭代执行聚合运算。问题在于每次iteration执行,返回的是一个时间点。Iterative 执行每次返回一条时间点,但对HoraeDB查询有可能需要访问大量时间线数据,这样的执行方式效率上并不可取;
  • 查询速度慢
    ◆ 从Cassandra查询数据是一个比较耗时的过程,会耗费比较长的时间在数据准备上;
    ◆ 整个计算过程需要等Cassandra中的数据全加载到内存中,才开始计算。
  • 内存和CPU资源消耗高
    ◆ HoraeDB有可能在短时间内下发太多Cassandra读请求,一个查询涉及到的Cassandra读请求同时异步提交,有可能在很短时间内向Cassandra下发大量的读请求。这样,一个大查询就有可能把底层的Cassandra打爆;
    ◆ 同时拉取大量的数据点到内存中,会导致HoraeDB内存打爆。

新的查询引擎针对老的查询计算引擎进行了优化:

借鉴传统数据库执行模式,引入Pipeline的执行模式。Pipeline包含不同的执行计算算子(operator),一个查询被物理计划生成器解析分解成一个Query Plan, 由不同的执行算子组成,DAG上的root operator负责驱动查询的执行,并将查询结果返回调用者。在执行层面,采用的是top-down需求驱动的方式,从root operator驱动下面operator的执行。这样的执行引擎架构具有如下优点:

  • 这种架构方式被很多数据库系统采用并证明是有效的;
  • 接口定义清晰,不同的执行计算算子可以独立优化,而不影响其他算子;
  • 易于扩展:通过增加新的计算算子,很容易实现扩展功能。比如目前查询协议里只定义了tag上的查询条件。如果要支持指标值上的查询条件(cpu.usage >= 70% and cpu.usage <=90%),可以通过增加一个新的ValueFilterOp来实现。

815f671913cf7781d16891595d36f62f.png

时序数据中,一般情况下,最近三个小时的数据是被查询比较多的热点数据,在HoraeDB中,为了加速这部分数据的访问,我们把最近三小时的数据放到自研的分布式缓存组件-TS-Cache中去。

TS-Cache是一个分布式的数据缓存系统,数据通过Hash算法均匀的分布在各个TS-Cache节点中。因为TS-Cache是个缓存组件,对数据的稳定性要求并没有那么高,所以我们的时序数据在TS-Cache中保存的是单副本。

0e0ab4e5512b78c7047fdf83c44248f4.png

数据在内存中的组织如上图所示,数据的顶层是一个SharedMap,它其实就是一个数组,目的是用来在内部对时序数据进行分片,降低gc对服务性能的影响,以及适当的减小锁的粒度,提升服务的读写性能。数据中的一个项就是SeriesMap,用来保存时序数据项和它的时序数据点的值,其内部的核心数据结构是一个跳表,跳表中的每一项对应的是一个时序数据中的一个项,在这边用SeriesData来进行表示。

SeriesData中有两个核心的数据结构,一个是cs,一个是blocks,cs是我们的一个流式压缩序列,这个流式压缩需要时根据上面所述的压缩算法来进行实现的,时序数据写入系统后,会直接写到这个压缩序列cs中,每隔一定时间,会把压缩序列中的数据导出,形成一个block数据块,写到blocks数组中。

为了用更少的内存来存储更多的数据,在TS-Cache中的数据是压缩成为block后进行存储,放到了上图的blocks数组中进行存储;数据压缩算法使用的是Gorilla这篇论文所提出的数据压缩算法,Gorilla引入了对timestamp和value的高压缩比算法,可大幅降低数据存储的大小。

Timestamp根据时间关联的条目进行差值计算、以及差值的差值计算得到占用字节数非常小的数值并进行保存。同样Value使用XOR算法进行计算得到占用存储更小的数值进行保存。

14138d254f6755cb5fb82f7876c66403.png
  • 时间戳压缩:时序数据的产生大部分情况下都是有周期性的,可能是30s、1m等,所以在存储时间戳的时候,我们只需要存储时间戳直接的差值;
  • 值压缩:通过对历史数据进行分析,发现大部分相邻时间的时序数据的值比较接近,而如果Value的值比较接近,则在浮点二进制表示的情况下,相邻数据的Value会有很多相同的位。整数型数据的相同位会更多。相同位比较多,意味着如果进行XOR运算的话会有很多位都为0,那么我们将当前值与前序值取XOR(异或)运算,保存XOR运算结果。

f82e84a9dfe241d3a40364df77031c9a.png

d2f91e26960d1c1c569131829cb26adf.png

HoraeDB作为一个海量时序数据的存储系统,经常会遇到一些突发性的流量高峰或者一些不合理的大查询、慢查询,如何保障HoraeDB的稳定性便成了一个要攻破的技术难点。

为了保障HoraeDB的稳定性,我们做了以下几个方面的工作:

  • 服务隔离;
  • HoraeDB读写分离:读写分别部署不同实例,避免大查询慢查询影响数据写入;
  • 计算处理层和存储层分离:数据写入和查询处理逻辑在HoraeDB层做,底层数据存储放到存储层进行;
  • 机房隔离:HoraeDB部署上支持多写,底层存储可以配置不同机房,实现数据多写互备,查询支持多机房HA查询;
  • 限流
    ◆ 在HTTP接口层支持接口调用频率进行限流;
    ◆ 针对写入,HoraeDB内部通过写入队列来感知当前写入负载,当队列满,即丢弃数据,保护HoraeDB正常工作;
    ◆ 查询上,基于查询时间跨度、时间线条数、数据点规模等进行了限制,避免大查询影响系统稳定性。
  • 查询负载管理:因为在我们的时序数据查询场景中,80%以上的情况都是查询最近三小时内的数据,都是一些查询和计算量比较小的查询任务,所以在查询上我们根据查询请求进行计算量简单预估,分为慢查询和快查询,分别放入到对应的查询任务队列,避免慢查询影响快查询;
  • 综合全面的服务监控指标,HoraeDB的问题可以快速被发现和定位。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/260874.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

飞雪迎春

转载于:https://www.cnblogs.com/ysx4221/p/3537810.html

高可用集群技术之corosync应用详解(一)

Corosync概述:Corosync是集群管理套件的一部分&#xff0c;它在传递信息的时候可以通过一个简单的配置文件来定义信息传递的方式和协议等。它是一个新兴的软件&#xff0c;2008年推出&#xff0c;但其实它并不是一个真正意义上的新软件&#xff0c;在2002年的时候有一个项目Ope…

一天总结

这几天忙着弄毕业设计和论文&#xff0c;有好几天都没总结了&#xff01;学习进度也慢了下来&#xff01;接下几天把毕业答辩弄好后&#xff01;把精力放在数据库和编程熟练度上&#xff01;还有很多要学习的多看书多敲代码&#xff01;最重要的是要多思考&#xff0c;要有自己…

电脑dns_win10系统dns错误如何解决「系统天地」

最近有位win10系统用户在使用电脑的过程当中&#xff0c;碰到了dns错误的情况&#xff0c;用户不知道如何解决&#xff0c;为此非常苦恼&#xff0c;那么win10系统dns错误如何解决呢?下面为大家分享win10电脑dns错误的解决方法。第一步&#xff1a;使用 ipconfig /flushdns 命…

第2章 Python 数字图像处理(DIP) --数字图像基础5 -- 算术运算、集合、几何变换、傅里叶变换等

目录数字图像处理所有的基本数字工具介绍算术运算集合运算和逻辑运算空间运算向量与矩阵运算图像变换图像和随机变量数字图像处理所有的基本数字工具介绍 算术运算 # 相加 img_ori cv2.imread("DIP_Figures/DIP3E_Original_Images_CH02/Fig0226(galaxy_pair_original).…

Windows安装cnpm报错 The operation was rejected by your operating system.

Windows在安装cnpm时出现如下错误 npm ERR! The operation was rejected by your operating system. npm ERR! Its possible that the file was already in use (by a text editor or antivirus), npm ERR! or that you lack permissions to access it. npm ERR! npm ERR! If y…

hao123电脑版主页_hao123浏览器 原生网民的记忆 一代站长的传奇

百度又有产品说再见了&#xff01;上线快8年的百度浏览器&#xff0c;再也不会更新了&#xff01;4月3日&#xff0c;百度浏览器官网发公告称&#xff0c;“桌面百度、百度工具栏、百度地址栏、百度极速浏览器&#xff0c;hao123浏览器&#xff0c;产品将不再更新&#xff0c;基…

小米平板2刷remix_昆明小米售后维修点手机维修怎么收费?小米手机拆机换屏教程...

小编最近修了很多小米手机&#xff0c;大部分维修的故障基本都是手机碎屏&#xff0c;手机换电池之类的&#xff0c;小编从事小米手机维修十余年&#xff0c;小米手机整体机型性价比还是不错的&#xff0c;所以市场上用的人还是比较多&#xff0c;尤其是在校学生&#xff0c;今…

第2章 Python 数字图像处理(DIP) --数字图像基础2 - 图像感知要素 - 图像取样和量化 - 空间分辨率和灰度分辨率

目录图像感知与获取一个简单的成像模型图像取样和量化空间分辨率和灰度分辨率图像感知与获取 一个简单的成像模型 我们用形如 f(x,y)f(x,y)f(x,y) 的二维函数来表示图像。在空间坐标 (x,y)处f(x, y)处 f(x,y)处f的值是一个标量&#xff0c;其物理意义由图像源决定&#xff0c…

外部资源获取

处理外部资源是很繁琐的事情&#xff0c;我们可能需要处理URL资源、File资源资源、ClassPath相关资源、服务器相关资源&#xff08;JBoss AS 5.x上的VFS资源&#xff09;等等很多资源。因此处理这些资源需要使用不同的接口&#xff0c;这就增加了我们系统的复杂性&#xff1b;而…

芯明天debug assertion failed_YJLV铝芯电力电缆的基本介绍

原标题&#xff1a;YJLV铝芯电力电缆的基本介绍YJLV铝芯电力电缆&#xff0c;型号全称&#xff1a;铝芯交联聚乙烯绝缘聚氯乙烯护套电力电缆。YJLV电缆的含义为&#xff1a;YJ----交联聚乙烯绝缘;L----线芯材质为铝材。V----聚氯乙烯护套。YJLV电缆工作温度为导体额定工作温度9…

第2章 Python 数字图像处理(DIP) --数字图像基础3 - 图像内插 - 最近邻内插 - 双线性插值 - 双三次内插 - 图像放大

目录图像内插放大图像图像内插 内插通常在图像放大、缩小、旋转和几何校正等任务中使用。内插并用它来调整图像的大小&#xff08;缩小和放大&#xff09;&#xff0c;缩小和放大基本上采用图像重取样方法 最近邻内插&#xff0c;这种方法将原图像中最近邻的灰度赋给了每个新…

然爸读书笔记(2014-2)----影响力

第一章&#xff1a;影响力的武器 动物可能会看到某种颜色的羽毛而变得具有攻击性&#xff0c;或者听到某种叫声久对自己的天敌呵护有加。动物的这种愚蠢机械反应在人类身上也有&#xff0c;在某个触发特征出现时&#xff0c;我们会不假思索的做出相应的反应&#xff0c;之所以会…

pb 如何导出csv_Firefox火狐浏览器将提供导出密码至本地的功能

6月2日&#xff0c;据外媒All About Lifehacks报道&#xff0c;Mozilla官方的bug报告页面显示&#xff0c;Firefox浏览器的导出或备份密码请求的问题在前两天被关闭&#xff0c;并被标记为已解决。据了解&#xff0c;该请求早在多年前就有人提出。如今被标记为已解决&#xff0…

跟着别人的感觉做网络推广之二

无意中闯入了站台网&#xff08;一家历史很悠久的分类信息网站&#xff0c;印象中比58 赶集 百姓创办时间还早。&#xff09; 进入后当然看医疗分类了&#xff1a; http://www.zhantai.com/ 站台网&#xff0c;不是大的省份网民不能位置定位时&#xff0c;默认进入的是北京分站…

iOS - OC 面向对象语法

1、类 1&#xff09;根类&#xff1a;因为类 NSObject 是层次结构的最顶层&#xff0c;因此称为根类。 可以将类称为子类&#xff08;subclass&#xff09;和父类&#xff08;superclass&#xff09;&#xff0c;也可以将类称为子类和超类。2&#xff09;分类&#xff0f;类别&…

第2章 Python 数字图像处理(DIP) --数字图像基础4 -- 像素间的一些基本关系 - 邻域 - 距离测试

目录像素间的一些基本关系像素的相邻像素距离测试import sys import numpy as np import cv2 import matplotlib import matplotlib.pyplot as plt import PIL from PIL import Imageprint(f"Python version: {sys.version}") print(f"Numpy version: {np.__ve…

iphone备忘录突然没了_苹果突然下架12 天猫:双11有惊喜!iPhone12 mini配色缩水

点击“蓝字”关注我们苹果旗舰店突然下架iPhone 12 天猫回应&#xff1a;请期待11.11的惊喜今天&#xff0c;有网友反馈&#xff0c;苹果天猫旗舰店的iPhone 12和iPhone 12 Pro被下架了。小编查看了下&#xff0c;天猫Apple Store旗舰店确实已经下降了目前在售的 iPhone 12 和 …

第3章 Python 数字图像处理(DIP) - 灰度变换与空间滤波1 - 灰度变换和空间滤波基础、Sigmoid激活函数

这里写目录标题本节的目标背景灰度变换和空间滤波基础本节的目标 了解空间域图像处理的意义&#xff0c;以及它与变换域图像处理的区别熟悉灰度变换所有的主要技术了解直方图的意义以及如何操作直方图来增强图像了解空间滤波的原理 import sys import numpy as np import cv2…

absolute 必须 relative_Workfine如何控制身份证号码必须为18位?

在信息化系统的设计中&#xff0c;由于业务的需要&#xff0c;我们往往需要设置许多控制项&#xff0c;以保证系统能够按照业务要求流转&#xff0c;必须出库数量不能超过库存&#xff0c;人员信息不能重复录入&#xff0c;考勤区间不能有交叉等。此篇以实例的方式告诉大家如果…