技术架构一些想到的

技术架构一些想到的

来源

听到了一个关于在AI时代下软硬件架构的挑战以及成功解决的部分场景

思考

所谓的技术架构,总是要考虑当前是什么样的技术架构,在使用了多少资源量下,解决了哪些问题。
技术的更迭也就是,新场景新问题

举个例子

在AI训练的场景下,其特点是,相对较高的延时,巨大的传输带宽,包括硬盘到内存的搬运,内存到现存的搬运。
在单机的情况下,是对PCIE和内存总线提出了新要求。
在分布式场景下,因为巨大的数据交换的消耗,TCP在这种情况下对于分包、重传等维护完整性的机制占用了巨量的CPU资源,还会占用将内存搬运到显存的CPU,使得计算效率下降。
那在这种场景下,就需要新的架构,尽可能的使得各个分系统直连,不需要CPU的参与。比如实现RDMA直通显存。

想到的

分析现状,实事求是,确实在方方面面都是相同的。

自训练

自训练

关键词摘取(国内)

供应链保持稳定
供应链重点技术突破
稳消费

关键词摘取(国外)

粮食
人口迁徙
技术封锁

运维标准化实践

运维标准化实践

现状

运维负责的事项有如下:

  • 维护现网机器运行状态
  • 接收上线单,完成应用上线
  • 对上线脚本进行审核

问题如下:

  • 没有办法对软件提供服务工程提供保证,也就是对外无法承诺时间,对内无法有效的反馈提升软件质量
  • 没有统一的资产管理平台,所有的资产均是通过excel交接
  • 对于流量等缺乏管控工具,无法提供可靠的无感升级以及可能存在的升级致使的事务中断,尤其涉及金融业务

对策

  1. 首先将零散的服务器资产的表格进行汇总,然后建设运维部门的统一管控平台
  2. 对资产进行标准化编号,避免需要运维人员去主动起名字,防止不同运维人员起名不统一
  3. 替换网关,由原来nginx替换为openresty+lua方案,用以解决优雅降级+流量切换
  4. 继续迭代原有账号服务,用来打通网关服务

最终实现效果

运维需要对流量进行控制,包括不限于

  • 能标记具体用户,要控制用户(包括不限于可能的真实环境测试账号)进入的服务器
  • 基于流量控制,能完成优雅降级和无感应用升级

将升级变成流量切换,时间短且可控
部署全部自动化

记一次性能优化问题

记一次性能优化问题

参与架构

代码设计

我们总假设,温度是一次次上报的,且点与点之间没有先后的顺序

很容易写出以下代码

For(EachTimeUploadData)

Pipe.collect(in,out,now)

遇到的问题

我们的不仅需要记录温度,还要记录压力和流量,而这些属性是归属于管道

这个时候会遇到一个巨大的问题,数据库的DeadLock

我们默认聚合根是Pipe,那么为了防止聚合根在两个线程中出现,故而数据库中是要对这一行开启事务的,意味着根所在一行是要锁行的,而测试中如果遇上同一根管道的首尾同时上报数据,那么就会发生DeadLock,更不要提某些情况下是要沿着管道将沿途所有的管道锁定的问题。

解决死锁

  1. 我们不能允许数据丢失
  2. 不能够对架构做大改动

要解决死锁的问题,最简单的办法时,我们只用一个线程来操作,在不考虑集群的情况下,将原有方案变更为,数据上报时候顺序写入文件,然后开启一个线程从文件头开始反序列化数据然后逐一写入数据库。

集群环境

在集群环境下,依旧有锁冲突的问题,那么冲突时候策略就可以考虑以下了,我选择了,冲突之后将数据放入队列尾部,这个时候代码逻辑上是没什么问题了

性能

可是上线之后发现,其写入性能仅在15s,注意是s,是秒,才完成50条入队消息的消费

在各种断点之后,依旧发现瓶颈在数据库与应用中

  1. 每次查询流量系统地址,30~50ms
  2. 每次查询流量,30~50ms
  3. 每次查询管道链条300~500ms

在一些支管上,单次插入可以达到最大5000ms

解决

  1. 增加管道标记父节点字段,而非靠查找所有管道再通过计算得出父节点
  2. 增加本地缓存和Redis缓存切换,以其在没有redis环境下可以降低查询流量系统地址的时延
  3. 优化流量和压力的Opc客户端,减少数据传输量
  4. 将于数据库交互中的插入和更新变为Batch形式

测试结果

消费50条数据仅需要300ms左右,

MariaDB单机双实例配置说明

MariaDB单机双实例配置说明

安装

  • 推荐操作系统,CentOS7, yum install mariadb-server

配置

以下配置均是以CentOS7来进行

  • 在/etc/my.cnf.d/建立两个文件3306.cnf,3307.cnf
[mysqld0]
basedir                               = /usr                        
character_set_server                  = utf8                        
collation_server                      = utf8_unicode_ci             
datadir                               = /opt/data0                  
default_storage_engine                = InnoDB                      
default_time_zone                     = '+8:00'                     
event_scheduler                       = 1                           
init_connect                          = 'set names utf8;'           
lower_case_table_names                = 1                           
memlock                               = 0                           
pid_file                              = /opt/data0/mysql.pid        
port                                  = 3306                        
skip_external_locking                 = 1                           
socket                                = /opt/data0/mysql.sock       
tmpdir                                = /dev/shm                    
user                                  = mysql                       


general_log                           = 0                           
general_log_file                      = /opt/data0/general_query.log
log_output                            = FILE                        
log_error                             = /opt/data0/mysqld.log       
log_warnings                          = 2                           
log_queries_not_using_indexes         = 1                           
log_slow_admin_statements             = 1                           
log_slow_verbosity                    = query_plan                  
long_query_time                       = 1                           
min_examined_row_limit                = 100                         
slow_query_log                        = 1                           
slow_query_log_file                   = /opt/data0/slow_query.log   


gtid_strict_mode                      = 1                           
transaction_isolation                 = READ-COMMITTED              


innodb_data_home_dir                  = /opt/data0                  
innodb_log_group_home_dir             = /opt/data0                  


innodb_undo_directory                 = /opt/data0                  


binlog_cache_size                     = 4M                          
binlog_checksum                       = crc32                       
binlog_format                         = row                         
expire_logs_days                      = 30                          
log_bin                               = /opt/data0/mysql-bin        
max_binlog_cache_size                 = 128M                        
max_binlog_size                       = 1G                          
sync_binlog                           = 1                           


max_relay_log_size                    = 1G                          
relay_log                             = /opt/data0/relay-bin        
relay_log_index                       = /opt/data0/relay-bin.index  
relay_log_info_file                   = relay-log.info              
relay_log_purge                       = 1                           
relay_log_recovery                    = 1                           
sync_relay_log                        = 10000                       


  • 创建数据库文件,其中应区分06,07所在的文件夹
mysql_install_db --datadir=/opt/data0 --user=mysql --force --defaults-file=/etc/my.cnf.d/3306.cnf
mysql_install_db --datadir=/opt/data1 --user=mysql --force --defaults-file=/etc/my.cnf.d/3307.cnf
  • 创建Systemd控制文件
mkdir /etc/systemd/system/[email protected]



#
# /etc/systemd/system/[email protected]
#

[Unit]
Description=Multi-Instance MariaDB Service
After=network.target
After=syslog.target


[Install]
WantedBy=multi-user.target


[Service]
User=mysql
Group=mysql
Type=forking
# true is needed for the ExecStartPre
PermissionsStartOnly=true
ExecStartPre=/usr/bin/mkdir -p /opt/data%i
ExecStartPre=/usr/bin/chown mysql:mysql /opt/data%i -R
ExecStart=/usr/bin/mysqld_multi start %i
ExecStop=/usr/bin/mysqld_multi stop %i
LimitNOFILE=102400
Restart=on-failure
RestartPreventExitStatus=1
PrivateTmp=true
  • 启动服务
systemctl start mariadb@{0,1}
  • 配置服务器账户密码
mysqladmin -hlocalhost -P3306 --protocol=tcp password abc
mysqladmin -hlocalhost -P3307 --protocol=tcp password abc
  • 本地登陆数据库,此时与正常操作数据库一致
mysql -P3306 --protocol=tcp -uroot -pabc
mysql -P3307 --protocol=tcp -uroot -pabc

供应链系统开发(一)

供应链系统开发(一)

一些概念

  1. 四流
    1. 商流(以下三个角色通过商品物权转移就是商流)
      • 原材料商
      • 材料加工商
      • 成品销售商
    2. 物流
      • 商品的包装
      • 商品的运输
      • 商品的存储
    3. 信息流
      • 运输单据
      • 发货单据
      • 交易单据
      • 各种各样是的整个供应链能运行的单据成为信息流
    4. 资金流
      • 货款结算
  2. 四流合一
    1. 四流间联动
      1. 以物流与信息流相互影响为例
        1. 商品运输过程中若出现损坏
        2. 需要在运输单据中记录一条损坏商品的信息
        3. 当这个运输单据到达货主处,货主要根据单据来验收,从而得到应收数量减少

    那么四流合一就很明白了,四流的内容能够完全反映出整个供应链链条的运作
    即四流可以与一条供应链等价

  3. 为了实现四流合一,又提出了三库的说法

    1. 供应商库
    2. 采购商库
    3. 商品库
  4. 为了提高整个供应链商品的运转效率,这时候需要有个服务商使得三库的链条运转顺畅得到了以下
    1. 服务商库
      1. 资金
      2. 物流

供应链系统开发(二)

供应链系统开发(二)

基本要素(确定调研方向,即确定参与系统的角色)

  • 上游供货商
  • 下游采购商
  • 资金提供商
  • 商品
  • 信息掮客/平台

以上是构成现代供应链的几个基础要素

要达成交易需要的几个步骤(业务流程分析)

  1. 下游采购商提出采购商品
  2. 下游采购商提出用款需求
  3. 下游采购商提出指定供货商/或者不关心
  4. 平台发布信息
  5. 平台撮合商品
  6. 平台撮合资金需求
  7. 平台撮合供应商

如下故事可以将场景闭环(业务场景分析)

  1. 客户向平台提出采购需求
  2. 平台分析需求,若仅有采购需求(直营)
    1. 从自有平台信息中寻找可撮合的交易对象
    2. 若存在则撮合交易
      1. 平台与供货商确定配送方式
      2. 客户付款
      3. 平台确认付款后,通知/直接将货物配送到指定地点
      4. 平台通知客户提货
      5. 客户通知平台提货完成
      6. 三方票据结算
      7. 故事结束
    3. 若不存在则
      1. 与客户沟通让其提供参考供应商
      2. 平台考察客户提供供应商,若准入则添加供应商至平台信息返回故事2.1
      3. 若不允许准入,则故事结束
  3. 若还有融资需求(垫资代采业务)
    1. 从自有平台信息中寻找可撮合的资金提供商
      1. 若存在则撮合交易
        1. 平台与资金提供商确定资金占用费用
        2. 平台与资金提供商确定供应商是否准入
        3. 平台与资金提供商确定商品是否准入
        4. 平台向客户返回费用协商结果及供应商,商品准入结果(项目信息)
        5. 若客户同意项目结果,则签署合同返回故事2.1
        6. 若客户不同意则返回3.1继续执行,直到所有资金商都无法满足客户需求
    2. 若无,则故事结束

到了这一步则系统的概设完成

参与角色与参与要素(业务场景涉及的表单、文件、票据等分析)

对照直营故事来细化
1. 询价单
2. 供应商目录
3. 商品目录
4. 采购合同
5. 销售合同
6. 采购订单
7. 销售订单
8. 发票
9. 通知
对照垫资代采故事细化
1. 资金提供商目录
2. 项目信息
3. 垫资代采合同
4. 与客户确认单据
按照此思路逐项分析,直至形成一个业务需求文档

如何拦截SQL

1、所有开发约定所有人都用公司某一个基础包,自己封装此基础包
2、所有人都爱用自己喜欢的ORM的话,推荐拦截jdbc驱动
3、采用alibaba的Druid连接池,自己写一个Filter。

几个基本单位

1 byte=8bit

1 int=4 byte

1 long =8 byte

1 short=2 byte

1 float=2 byte

1 double = 8 byte

= =其实我想吐槽的是。。我压根分不清他们翻译成中文之后的关系。。。神特么非要推广专有名词的中文化