Rust分布式账务系统 - 胡宇第三届中国 Rust 开发者大会 Rust 构建分布式账务系统 在 Fintech 公司落地 Rust 项目的经验分享 Airwalle x 胡宇 Airwallex 我们是一家跨境支付领域的 Fintech 独角兽 关于我们 E2 轮 Fintech 独角兽,业务遍布全球 关于我们: Airwallex 墨尔本 新加坡 伦敦 深圳 香港 北京 旧金山 上海 东京 提供高效,低成本的数字银行服务 关于我们: Airwallex 从设计架构到实现细节 项目介绍 分布式账务系统 Fintech 互联网 正确性 bug= 资损 bug 不可怕,快速迭代 可靠性 丢数据 = 资损 允许数据丢失 性能 超低延迟 + 高吞吐 超高吞吐 交易日志 审计,监管 调试使用 分布式账务系统 Fintech 领域中的软件与互联网软件的不同 需求分析 支付处理: ● 转账 高可用:在部分节点失效的情况下,依旧可以提供正确的 服务 超低延迟:实时交易,超低响应延迟 水平扩展性:利用分布式事务实现钱包集群的的水平扩 展,应对高达 100 万 TPS 的流量 可演化性:业务逻辑与底层 API 解耦,当业务发生改变 时,底层 API 不用改变 分布式账务系统 设计理念 - Rust 是我们可靠的基石 分布式账务系统 存算分离 API 解耦 读写分离 层级账号 Rust ● 事务层与账户层分0 码力 | 27 页 | 12.60 MB | 1 年前3
新一代分布式高性能图数据库的构建 - 沈游人新一代分布式高性能图数据库的构建 北京海致星图科技有限公司 2023-06-18 沈游人 数据库与大数据专场 海致简介—企业级知识图谱开创者 专业顶尖技术团队支撑 超 700 人团队,其中 80% 为技术人员,创始团队在完成全球第一个中文知 识图谱网站研发后,探索知识图谱技术在企业领域的应用。 2021 年,海致院 士专家工作站成立,站内清华大学计算机博士生占比达 90% 以上。 实时风控对图库的性能挑战( OLTP 毫秒级响应) • 海致图平台产品服务于金融、政府行业有大量业务经验积累(接近客户需求) • 现有开源产品无法满足要求(受限于基础架构设计,优化性能有限) 新一代分布式图数据库需具备的特性 特性 信 雅 达 • 高可用 • 一致性(事 务) • 高性能 • 低资源消耗 • 易用 • 功能丰富 AtlasGraph 关键特性 云原生 Cloud-Native ,可扩展的分析引擎支持更复 杂的数据挖掘和机器学习场景 MPP Massively Parallel Processing 架构,大规模集群 分布式存储及并行计 算, Shared Nothing 模式支 持存储计算分离 高性能 基于 Rust 开发的分布式存储引 擎及图计算引擎,精细的内存 管理设计,内置索引系统,支 持毫秒级的并发查询响应速度 易用 AQL(Atlas Graph Query0 码力 | 38 页 | 24.68 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 15 C++ 系列课:字符与字符串C++ 字符串类 第 3 章 C 语言字符串操作繁琐 封装的 std::string 应运而生 封装的 std::string 应运而生 • string 可以从 const char * 隐式构造: • string s = “hello”; • string 具有 + 、 += 、 == 等直观的运算符重载: • string(“hello”) + string(“world”) == string 类,其成员有两个: char *ptr; size_t len; • 第二个成员用来确定结尾的位置,不需要 ‘ \0’ 结尾。 • 因此 string 类从 C 字符串构造时,可以额外指定一个长度: • string(“hello”, 3) 会得到 “ hel” • ↑ len 为 3 , ptr 指向 ’ h’ ,只保留前三个字符 • string(“hello”, 12) 会得到 字符串 printf 指定类型繁琐 • printf 必须告诉他是字符串( %s )还是整数( %d )还是 字符( %c ),必须和右边的参数一致,初学者容易搞错 。 • 而且即使搞错了也能正常编译通过(一些高级的编译器会 给出警告),但是运行结果不对,或者还有可能崩溃。 泛型的 iostream 应运而生 • 得益于 C++ 的重载技术, cout 不用你手动指定类型,他 会自动识0 码力 | 162 页 | 40.20 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 03 现代 C++ 进阶:模板元编程,后半段主要介绍并行编程与优化。 1.课程安排与开发环境搭建: cmake 与 git 入门 2.现代 C++ 入门:常用 STL 容器, RAII 内存管理 3.现代 C++ 进阶:模板元编程与函数式编程 4.编译器如何自动优化:从汇编角度看 C++ 5.C++11 起的多线程编程:从 mutex 到无锁并行 6.并行编程常用框架: OpenMP 与 Intel TBB 7.被忽视的访存优化:内存带宽与 以上( GPU 专题) 为什么需要模板函数( template ) • 避免重复写代码。 • 比如,利用重载实现“将一个数乘以 2” 这个 功能,需要: 为什么面向对象在 HPC 不如函数式和元编程香了? 这个例子要是按传统的面向对象思想,可能是这样: 令 Int, Float, Double 继承 Numeric 接口类并实现 ,其中 multiply(int) 作为虚函数。然后定义: twice(“hello”) 这样去调用,他不会自动隐 式转换到 std::string 并调用那个特化函数 ,而是会去调用模板函数 twice(“hello”) ,从而出错。 • 可能的解决方案: SFINAE 。 模板函数:默认参数类型 • 但是如果模板类型参数 T 没有出现在函数 的参数中,那么编译器就无法推断,就不 得不手动指定了。 • 但是,可以通过 • template 0 码力 | 82 页 | 12.15 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 02 现代 C++ 入门:RAII 内存管理,后半段主要介绍并行编程与优化。 1.课程安排与开发环境搭建: cmake 与 git 入门 2.现代 C++ 入门:常用 STL 容器, RAII 内存管理 3.现代 C++ 进阶:模板元编程与函数式编程 4.编译器如何自动优化:从汇编角度看 C++ 5.C++11 起的多线程编程:从 mutex 到无锁并行 6.并行编程常用框架: OpenMP 与 Intel TBB 7.被忽视的访存优化:内存带宽与 还包括了用于销毁的解构函数( destructor ) 离开 {} 作用域自动释放 手动释放 RAII :避免犯错误 与 Java , Python 等垃圾回收语言不同, C++ 的 解构函数是显式的,离开作用域自动销毁,毫不含 糊(有好处也有坏处,对高性能计算而言利大于 弊) 如果没有解构函数,则每个带有返回的分 支都要手动释放所有之前的资源 : RAII :异常安全( exception-safe 自定义构造函数:单个参数(避免陷阱) 避免陷阱体现在哪里? • 加了 explicit 表示必须用 () 强制转换。 • 否则 show(80) 也能编译通过! • 所以,如果你不希望这种隐式转换, • 请给单参数的构造函数加上 explicit 。 • 比如 std::vector 的构造函数 vector(size_t n) 也是 explicit 的。 explicit 对多个参数也起作用!0 码力 | 96 页 | 16.28 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 13 C++ STL 容器全解之 vector是一个模板类,第一个模板参数是数组里 元素的类型。 • 例如,声明一个元素是 int 类型的动态数组 a : • vectora; vector 容器:构造函数和 size • vector 可以在构造时指定初始长度。 • explicit vector(size_t n); • 例如,要创建一个长度为 4 的 int 型数组 : • vector a(4); • 之后可以通过 a.size() &operator[](size_t i) noexcept; • int const &operator[](size_t i) const noexcept; vector 容器:构造函数 • 除了先指定大小再一个个构造之外,还可 以直接利用初始化列表( C++11 新特性) 在构造时就初始化其中元素的值。 • 例如创建具有 6, 1, 7, 4 四个元素的 vector : • vector vector a{4}; • 会得到长度为 1 只有一个元素 4 的数组。 • 如果需要长度为 4 ,元素全部为 0 的数组,必 须用圆括号 () 而不是花括号 {} ,这样才能保证 调用他的显式( explicit )构造函数: • vector a(4); • 会得到长度为 4 元素全为 0 的数组。 • vector(initializer_list list); 0 码力 | 90 页 | 4.93 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 08 CUDA 开启的 GPU 编程__host__ __device__ ,从而两边都可以调用。 • 因为 constexpr 通常都是一些可以内联的函数,数学计 算表达式之类的,一个个加上太累了,所以产生了这个 需求。 • 不过必须指定 --expt-relaxed-constexpr 这个选项才能 用这个特性,我们可以用 CMake 的生成器表达式来实 现只对 .cu 文件开启此选项(不然给到 gcc 就出错 了)。 • 示当前编译所针对的 GPU 的架构版本号 是多少。这里是 520 表示版本号是 5.2.0 ,最后一位始终是 0 不用管,我们 通常简称他的版本号为 52 就行了。 • 这个版本号是编译时指定的版本,不是运 行时检测到的版本。编译器默认就是最老 的 52 ,能兼容所有 GTX900 以上显卡。 https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index ,他的版本号是 75 ,因 此最适合他用的指令码版本是 75 。 • 如果不指定,编译器默认的版本号是 52 ,他是针对 GTX900 系列显卡的。 • 不过英伟达的架构版本都是向前兼容的,即版本号为 75 的 RTX2080 也可以运行版本号为 52 的指令码,虽然 不够优化,但是至少能用。也就是要求:编译期指定的 版本 ≤ 运行时显卡的版本。 CMAKE_CUDA_ARCHITECTURES0 码力 | 142 页 | 13.52 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - Zeno 中的现代 C++ 最佳实践 Derived 的拷贝 构造函数 Derived(Derived const &) 。 CRTP (Curiously Recurring Template Pattern / 奇异递归模板模 式 ) • 形如 struct Derived : Base{}; • 基类模板参数包含派生类型的,这种就是传说中的 CRTP 。包含派生类型是为了能调用派 生类的某些函数(我们这个例子中是拷贝构造函数)。 IObjectClone 新增一个模板参数 Base ,其默认值为 IObject 。 • 这样当用户需要的时候就 • 可指定第二个参数 Base , • 从而控制 IObjectClone 的 • 基类,也就相当于自己继 • 承自那个 Base 类了,不 • 指定的话就默认 IObject 。 IObject :一切 Zeno 对象的公共基类 IObjectClone :自动实现所有 VDBGrid 作为所有网格类的基类提供各个 操作做为虚函数, VDBGridWrapper 则是 那个实现了擦除的包装类。 Zeno 节点系统 • 节点在 Zeno 中所扮演的角色,实际上相当于函数式编程中的函数。 • 节点输入若干个对象,并输出若干个对象。 Zeno 节点系统 • 节点的输出可以连线到另一个节点的输入上,相当于函数的调用和返回。 • 众多节点的组合,可以形成更强大的功能,这就是 0 码力 | 54 页 | 3.94 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 14 C++ 标准库系列课 - 你所不知道的 set 容器第一个 T 是容器内元素的类 型,例如 int 或 string 等。 • 第二个 CompT 定义了你想 要的比较函子, set 内部会 调用这个函数来决定怎么排 序。 • 如果 CompT 不指定,默认 会直接用运算符 < 来比较。 • 这里我们定义个 MyComp 作为比较函子,和默认的一 样用 < 来比较,所以没有变 化。 set 的排序:自定义排序函数 • 恶搞一下,这里我们把比较 1 。 • 个数为 0 就说明集合中没有该元素。 个数为 1 就说明集合中存在该元素 。 • 因为 int 类型能隐式转换为 bool , 所以 != 0 可以省略不写。 • size_t count(int const &val) const; 从 set 中删除指定元素 • set.erase(x) 可以删除集合中值为 x 的元素。 • erase 返回一个整数,表示被他删除元素的个 的情况很像,因为 set 中不会有重复的元素,所以 erase 只可能返回 0 或 1 ,表示是否删除成功。 • size_t erase(int const &val); 从 set 中删除指定元素 • erase 还支持迭代器作为参数。 • set.erase(it) 可以删除集合位于 it 处的 元素。用法举例: • set.erase(set.find(x)) 会删除集合中值0 码力 | 83 页 | 10.23 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 05 C++11 开始的多线程编程,后半段主要介绍并行编程与优化。 1.课程安排与开发环境搭建: cmake 与 git 入门 2.现代 C++ 入门:常用 STL 容器, RAII 内存管理 3.现代 C++ 进阶:模板元编程与函数式编程 4.编译器如何自动优化:从汇编角度看 C++ 5.C++11 起的多线程编程:从 mutex 到无锁并行 6.并行编程常用框架: OpenMP 与 Intel TBB 7.被忽视的访存优化:内存带宽与 • 可以用 std::this_thread::sleep_for 替代 Unix 类操作系统专有的的 usleep 。他可 以让当前线程休眠一段时间,然后继续。 • 而且单位也可以自己指定,比如这里是 milliseconds 表示毫秒,也可以换成 microseconds 表示微秒, seconds 表示 秒, chrono 的强类型让单位选择更自由 。 睡到时间点: wait() 会无限等下去。 • 而 wait_for() 则可以指定一个最长等待时间, 用 chrono 里的类表示单位。他会返回一个 std::future_status 表示等待是否成功。 • 如果超过这个时间线程还没有执行完毕,则放 弃等待,返回 future_status::timeout 。 • 如果线程在指定的时间内执行完毕,则认为等 待成功,返回 future_status::ready0 码力 | 79 页 | 14.11 MB | 1 年前3
共 28 条
- 1
- 2
- 3













