沉浸式学习PostgreSQL|PolarDB 2: 电商高并发秒杀业务、跨境电商高并发队列消费业务

本文涉及的产品
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介: 业务场景介绍: 高并发秒杀业务秒杀业务在电商中最为常见, 可以抽象成热点记录(行)的高并发更新. 而通常在数据库中最细粒度的锁是行锁, 所以热门商品将会被大量会话涌入, 出现锁等待, 甚至把数据库的会话占满, 导致其他请求无法获得连接产生业务故障.业务场景介绍: 高并发队列消费业务在跨境电商业务中可能涉及这样的场景, 由于有上下游产业链的存在,1、用户下单后, 上下游厂商会在自己系统中生成一笔订单记录并反馈给对方,2、在收到反馈订单后, 本地会先缓存反馈的订单记录队列,3、然后后台再从缓存取出订单并进行处理.

作者

digoal

日期

2023-08-22

标签

PostgreSQL , PolarDB , 数据库 , 教学


背景

非常欢迎数据库用户提出场景给我, 在此issue回复即可, 一起来建设沉浸式数据库学习教学素材库, 帮助开发者用好数据库, 提升开发者职业竞争力, 同时为企业降本提效.

本文的实验可以使用永久免费的阿里云云起实验室来完成.

如果你本地有docker环境也可以把镜像拉到本地来做实验:

x86_64机器使用以下docker image:

Apple Chip机器使用以下docker image:

业务场景介绍: 高并发秒杀业务

秒杀业务在电商中最为常见, 可以抽象成热点记录(行)的高并发更新. 而通常在数据库中最细粒度的锁是行锁, 所以热门商品将会被大量会话涌入, 出现锁等待, 甚至把数据库的会话占满, 导致其他请求无法获得连接产生业务故障.

实现和对比

创建商品表, 测试扣减库存操作.

drop table IF EXISTS tbl;  
create unlogged table tbl (   -- 测试使用unlogged table减少redo   
  id int primary key,  -- 商品id  
  cnt int,             -- 库存  
  ts timestamp        -- 修改时间  
);

插入一条记录, 初始设置20亿库存.

insert into tbl values (1, 2000000000, now());

增加实验环境数据库最大连接数

postgres=# alter system set max_connections =2000;  
ALTER SYSTEM  
docker stop pg  
docker start pg  
docker exec -ti pg bash

传统方法 设计和实验

编写测试脚本, 扣件商品id=1的库存.

vi t1.sql  
update tbl set cnt=cnt-1, ts=now() where id=1;

使用1920个并发连接进行测试:

pgbench -M prepared -n -r -f ./t1.sql -P 1 -c 1920 -j 8 -T 120

结果:

transaction type: ./t1.sql  
scaling factor: 1  
query mode: prepared  
number of clients: 1920  
number of threads: 8  
duration: 120 s  
number of transactions actually processed: 31875  
latency average = 7729.207 ms  
latency stddev = 15626.227 ms  
initial connection time = 1784.073 ms  
tps = 230.270300 (without initial connection time)  
statement latencies in milliseconds:  
      7722.072  update tbl set cnt=cnt-1, ts=now() where id=1;

tps: 230.270300

PolarDB|PG新方法1 设计和实验

使用skip locked跳过被锁的行, 减少冲突等待时长.

编写测试脚本, 扣件商品id=1的库存. 使用skip locked跳过被锁的行, 减少等待. 如果能返回商品id, 表示更新成功, 如果返回0条记录, 表示没有拿到锁.

vi t1.sql  
with tmp as (  
  select id from tbl where id=1 for update skip locked  
)  
update tbl set cnt=cnt-1, ts=now() from tmp where tbl.id=tmp.id returning tbl.id;

使用1920个并发连接进行测试:

pgbench -M prepared -n -r -f ./t1.sql -P 1 -c 1920 -j 8 -T 120

结果:

transaction type: ./t1.sql  
scaling factor: 1  
query mode: prepared  
number of clients: 1920  
number of threads: 8  
duration: 120 s  
number of transactions actually processed: 2847721  
latency average = 77.784 ms  
latency stddev = 138.536 ms  
initial connection time = 1703.949 ms  
tps = 23915.353056 (without initial connection time)

tps: 23915.353056

PolarDB|PG新方法2 设计和实验

清理环境垃圾:

vacuum full tbl;

编写测试脚本, 扣件商品id=1的库存. 同时使用pg_try_advisory_xact_lock预判是否能拿到商品id=1的锁, 如果能返回商品id, 表示更新成功, 如果返回0条记录, 表示没有拿到锁.

vi t2.sql  
update tbl set cnt=cnt-1, ts=now() where id=1 and pg_try_advisory_xact_lock(1) returning id;

使用1920个并发连接进行测试:

pgbench -M prepared -n -r -f ./t2.sql -P 1 -c 1920 -j 8 -T 120

结果:

transaction type: ./t2.sql  
scaling factor: 1  
query mode: prepared  
number of clients: 1920  
number of threads: 8  
duration: 120 s  
number of transactions actually processed: 13917081  
latency average = 12.053 ms  
latency stddev = 30.646 ms  
initial connection time = 1879.213 ms  
tps = 116928.030422 (without initial connection time)  
statement latencies in milliseconds:  
        12.056  update tbl set cnt=cnt-1, ts=now() where id=1 and pg_try_advisory_xact_lock(1) returning id;

tps: 116928.030422

对照

test case 传统方法 tps skip locked方法 tps advisory lock方法 tps 性能提升倍数
高并发秒杀(热点记录更新) 230.270300 23915.353056 116928.030422 507.785982

业务场景介绍: 高并发队列消费业务

《高并发队列处理业务的数据库性能优化 - IO扫描|CPU计算浪费 , 锁冲突 , 垃圾索引扫描浪费》

在跨境电商业务中可能涉及这样的场景, 由于有上下游产业链的存在,

  • 1、用户下单后, 上下游厂商会在自己系统中生成一笔订单记录并反馈给对方,
  • 2、在收到反馈订单后, 本地会先缓存反馈的订单记录队列,
  • 3、然后后台再从缓存取出订单并进行处理.

这个过程的核心流程:

  • 1、高速写入队列、
  • 2、从队列按先后顺序提取并高速处理、
  • 3、从队列清除已处理订单记录.

如果是高并发的处理, 因为大家都按一个顺序获取, 容易产生热点, 可能遇到取出队列遇到锁冲突瓶颈、IO扫描浪费、CPU计算浪费的瓶颈. 以及在清除已处理订单后, 索引版本未及时清理导致的回表版本判断带来的IO浪费和CPU运算浪费瓶颈等.

  • 文末的《打车与宇宙大爆炸的关系》一文有相似问题和优化方法, 思路类似.

接下来的实验将给出“队列处理业务的数据库性能优化”优化方法和demo演示. 性能提升10到20倍.

实现和对比

1、上游写入订单处理队列表

drop table if exists t_order_q;  
create unlogged table t_order_q (    
  id serial8 primary key,   -- 自增主键    
  order_id uuid unique,     -- 上游传递过来的订单号    
  cts timestamp not null    -- 上游传递过来的订单创建时间     
);     
-- create index on t_order_q (cts); -- 如果按订单时间先后取出处理, 则需要创建时间字段索引.  本实验按自增主键顺序处理, 则不需要时间索引.

2、取出并处理后的订单状态表

drop table if exists t_order_u;  
create unlogged table t_order_u (    
  id serial8 primary key,   -- 自增主键    
  order_id uuid unique,     -- 上游传递过来的订单号    
  cts timestamp not null,    -- 上游传递过来的订单创建时间     
  uts timestamp not null,   -- 订单处理时间    
  status int not null       -- 订单处理状态标记     
);

3、写入100万条订单队列

truncate t_order_q;  
insert into t_order_q (order_id, cts) select gen_random_uuid(), clock_timestamp() from generate_series(1,1000000);

传统方法 设计和实验

1、写pgbench压测脚本, 从t_order_q队列取出一条订单信息, 然后处理这条订单信息, 并将处理结果插入到t_order_u处理结果表.

vi t1.sql    
begin;    
select id as vid from t_order_q order by id for update limit 1 \gset    
with tmp as     
  (delete from t_order_q where id = :vid returning order_id, cts)    
insert into t_order_u (order_id,cts,uts,status) select tmp.order_id, tmp.cts, now(), 1 from tmp;     
end;

2、压测256个并发消耗队列, 平均每个连接处理3906个事务.

select 1000000/256.0;    
3906.2500000000000

3、压测结果

pgbench -M extended -f ./t1.sql -n -r -P 1 -c 256 -j 8 -t 3906
transaction type: ./t1.sql  
scaling factor: 1  
query mode: extended  
number of clients: 256  
number of threads: 8  
number of transactions per client: 3906  
number of transactions actually processed: 999936/999936  
latency average = 111.243 ms  
latency stddev = 125.890 ms  
initial connection time = 234.312 ms  
tps = 2280.326174 (without initial connection time)

tps: 2280.326174

PolarDB|PG新方法1 设计和实验

先重新生成测试数据.

1、写pgbench压测脚本, 从t_order_q队列取出一条订单信息, 使用skip locked跳过被其他会话正在处理的订单, 然后处理这条订单信息, 并将处理结果插入到t_order_u处理结果表.

vi t2.sql    
begin;    
select id as vid from t_order_q order by id for update skip locked limit 1 \gset    
with tmp as     
  (delete from t_order_q where id = :vid returning order_id, cts)    
insert into t_order_u (order_id,cts,uts,status) select tmp.order_id, tmp.cts, now(), 1 from tmp;     
end;

2、压测结果

pgbench -M extended -f ./t2.sql -n -r -P 1 -c 256 -j 8 -t 3906
transaction type: ./t2.sql  
scaling factor: 1  
query mode: extended  
number of clients: 256  
number of threads: 8  
number of transactions per client: 3906  
number of transactions actually processed: 999936/999936  
latency average = 65.596 ms  
latency stddev = 104.377 ms  
initial connection time = 234.029 ms  
tps = 3795.525190 (without initial connection time)

tps: 3795.525190

PolarDB|PG新方法2 设计和实验

先重新生成测试数据.

1、写pgbench压测脚本, 从t_order_q队列取出1条订单数据(并且使用ad lock对队列ID加事务锁, 判断是否正在处理, 事务结束自动释放ad lock. ad lock也经常被用于秒杀场景泄压.), 然后处理这条订单信息, 并将处理结果插入到t_order_u处理结果表.

vi t3.sql    
with tmp as     
  (delete from t_order_q where ctid = (select ctid from t_order_q where pg_try_advisory_xact_lock(id) order by id limit 1) returning order_id, cts)    
insert into t_order_u (order_id,cts,uts,status) select tmp.order_id, tmp.cts, now(), 1 from tmp;  
- 或  
-   
- begin;  
- select id as v_id from t_order_q where pg_try_advisory_xact_lock(id) order by id limit 1 \gset  
- with tmp as (delete from t_order_q where id = :v_id returning order_id, cts)   
-   insert into t_order_u (order_id,cts,uts,status) select tmp.order_id, tmp.cts, now(), 1 from tmp;     
- end;  
-   
- 或(sleep 模拟应用拿到需要处理的订单后的应用端操作增加的耗时.)  
-   
- begin;   
- select id as v_id from t_order_q where pg_try_advisory_xact_lock(id) order by id limit 1 \gset  
- \sleep 10ms  
- with tmp as (delete from t_order_q where id = :v_id returning order_id, cts)   
-   insert into t_order_u (order_id,cts,uts,status) select tmp.order_id, tmp.cts, now(), 1 from tmp;     
- end;

2、压测结果

pgbench -M extended -f ./t3.sql -n -r -P 1 -c 256 -j 8 -t 3906
transaction type: ./t3.sql  
scaling factor: 1  
query mode: extended  
number of clients: 256  
number of threads: 8  
number of transactions per client: 3906  
number of transactions actually processed: 999936/999936  
latency average = 20.404 ms  
latency stddev = 45.780 ms  
initial connection time = 239.823 ms  
tps = 12283.493260 (without initial connection time)

tps: 12283.493260

PolarDB|PG新方法3 设计和实验

先重新生成测试数据. 使用分区表, 每次从1个分区队列获取订单, 从物理层面进一步减少IO 和 CPU 浪费.

1、上游写入订单处理队列表

drop table if exists t_order_q;  
create unlogged table t_order_q (    
  id serial8 primary key,   -- 自增主键    
  order_id uuid ,     -- 上游传递过来的订单号    
  cts timestamp not null    -- 上游传递过来的订单创建时间     
) PARTITION BY hash (id) ;     
-- create index on t_order_q (cts); -- 如果按订单时间先后取出处理, 则需要创建时间字段索引.  本实验按自增主键顺序处理, 则不需要时间索引.     
do language plpgsql $$  
declare  
  x int := 256;  
begin  
for i in 0..x-1 loop  
  execute format ($_$create unlogged table t_order_q_%s PARTITION OF t_order_q FOR VALUES WITH (MODULUS %s, REMAINDER %s);$_$,   
    i, x, i  
  );  
end loop;  
end  
$$;

2、取出并处理后的订单状态表

drop table if exists t_order_u;  
create unlogged table t_order_u (    
  id serial8 primary key,   -- 自增主键    
  order_id uuid unique,     -- 上游传递过来的订单号    
  cts timestamp not null,    -- 上游传递过来的订单创建时间     
  uts timestamp not null,   -- 订单处理时间    
  status int not null       -- 订单处理状态标记     
);

3、写入100万条订单队列

truncate t_order_q;  
insert into t_order_q (order_id, cts) select gen_random_uuid(), clock_timestamp() from generate_series(1,1000000);

4、编写压测函数, 在函数中根据pgbench client_id来取模选择对应的表分区进行处理. (在实际的应用中也可以使用类似手段.)

《PostgreSQL Oracle 兼容性之 - DBMS_SQL(存储过程动态SQL中使用绑定变量-DB端prepare statement)》

create or replace function dyn_pre_orders(partitions int, client_id int) returns int8 as $$  
declare  
  suffix int := mod(client_id, partitions);   
begin  
  execute format('execute p%s(%s)', suffix, client_id);   
  return 0;   
  exception when others then  
    execute format('prepare p%s(int) as   
      with tmp as     
        (delete from t_order_q_%s where ctid = (select ctid from t_order_q_%s where pg_try_advisory_xact_lock(id) order by id limit 1) returning order_id, cts)    
      insert into t_order_u (order_id,cts,uts,status) select tmp.order_id, tmp.cts, now(), 1 from tmp;', suffix, suffix, suffix);   
    execute format('execute p%s(%s)', suffix, client_id);    
    return 0;  
end;  
$$ language plpgsql strict;

5、写pgbench压测脚本.

vi t4.sql    
\set clients 256  
select dyn_pre_orders(:clients, :client_id);

6、压测结果

pgbench -M extended -f ./t4.sql -n -r -P 1 -c 256 -j 8 -t 3906
transaction type: ./t4.sql  
scaling factor: 1  
query mode: extended  
number of clients: 256  
number of threads: 8  
number of transactions per client: 3906  
number of transactions actually processed: 999936/999936  
latency average = 4.400 ms  
latency stddev = 12.287 ms  
initial connection time = 250.656 ms  
tps = 49892.858208 (without initial connection time)  
statement latencies in milliseconds:  
         0.000  \set clients 256  
         4.400  select dyn_pre_orders(:clients, :client_id);

tps: 49892.858208

对照

test case 传统方法 tps skip locked方法 tps advisory lock方法 tps advisory lock + 分区方法 tps 性能提升倍数
高并发秒杀(热点记录更新) 2280.326174 3795.525190 12283.493260 49892.858208 21.9

知识点

1、advisory lock:

轻量锁, 根据机器性能的不同, 每秒预计可处理50万次左右的轻量锁请求.

轻量锁分为共享、独占、无堵塞尝试等请求, 同时持有锁的范围分为会话或事务周期.

例如本例用到的 pg_try_advisory_xact_lock 表示事务级别尝试请求ID为N的轻量锁, 如果没有其他事务持有则返回true, 否则返回false.

更多信息请参考末尾文章.

2、select for update skip locked

跳过被锁的行, 与advisory lock功能相似, 但是实现方法不一样, skip locked经过的逻辑比advisory lock长(skip locked要经过tuple search, 已经到表内部. 而advisory lock在搜索tuple之前已经完成了判断), 所以效率与之相比偏低.

思考

1、为什么第一种方法会这么慢呢?

1920个连接中, 同一时刻只有1个连接能持有行锁, 它更新完释放锁, 然后等待队列中的第一个会话得到锁后进行更新. 因此始终有1919个连接处于等待状态, 处于等待队列中的第1920个会话要等的时间最长.

在实际秒杀场景中, 库存可能没有这么多, 所以等待都是浪费掉的, 因为等拿到锁可以更新的时候, 库存都已经变成0了, 前面等于白白占用了会话连接和数据库资源.

这种场景最容易引起数据库雪崩.

2、对于业务场景2, 还有什么方法提升性能?

2.1、减少浪费的IO和cpu计算:

  • 在并发的情况下, order by id limit 1需要扫描若干行, 而不是1行, 因为可能有些ID已经被ad lock touch了, 浪费的pg_try_advisory_xact_lock() cpu ops计算次数约等于 n + n-1 + n-2 + ... + n-n, 浪费的IO约等于N.

优化方法:

  • 固定N个链接, 按ID hash mod 取不同的数据分片, 从而减少浪费的IO和cpu计算.
  • 或者将队列表拆分成几个分区表, 入库的时候 按id hash mode, 每个分区分配给不同的进程取数, 从而减少冲突和浪费的扫描提高并发.

2.2、提高index vacuum的频率, 减少因没有index version导致的垃圾数据判断带来的cpu和回表的IO浪费. 提升autovacuum_work_mem, 容纳下所有dead tuple ctid避免多次扫描index.

优化方法:

  • 配置参数autovacuum_naptime、autovacuum_work_mem(或者老版本 maintenance_work_mem)即可.

2.3、使用并行vacuum, 配置max_parallel_maintenance_workers.

2.4、配置vacuum使用prefetch blocks, 减少io delay带来的vacuum 比较久的问题. (适合 单次IO delay较高, 但是吞吐没有瓶颈的云盘)

2.5、一次取出多条, 批量处理.

2.6、使用IOPS较高, 单次IO delay较低的本地nvme SSD.

更多请参考末尾文章.

参考

201801/20180105_03.md 《PostgreSQL 秒杀4种方法 - 增加 批量流式加减库存 方法》
201711/20171107_31.md 《HTAP数据库 PostgreSQL 场景与性能测试之 30 - (OLTP) 秒杀 - 高并发单点更新》
201611/20161117_01.md 《聊一聊双十一背后的技术 - 不一样的秒杀技术, 裸秒》
201509/20150914_01.md 《PostgreSQL 秒杀场景优化》
202101/20210121_04.md 《PostgreSQL 用advisory lock 限制每一个分组中最多有多少条记录》
202005/20200517_01.md 《PostgreSQL 变态需求实现 - 堵塞式读, 不堵塞写 - 串行读,并行写 - advisory lock》
201810/20181018_04.md 《Locking issue with concurrent DELETE / INSERT in PostgreSQL - 解法 advisory lock》
201707/20170720_01.md 《advisory lock 实现高并发非堵塞式 业务锁》
201705/20170507_02.md 《PostgreSQL 使用advisory lock实现行级读写堵塞》
201610/20161020_02.md 《PostgreSQL 无缝自增ID的实现 - by advisory lock》
201610/20161018_01.md 《PostgreSQL 使用advisory lock或skip locked消除行锁冲突, 提高几十倍并发更新效率》
202308/20230805_01.md 《高并发队列处理业务的数据库性能优化 - IO扫描|CPU计算浪费 , 锁冲突 , 垃圾索引扫描浪费》
202106/20210601_01.md 《重新发现PostgreSQL之美 - 10 内卷 & 大禹治水》
201810/20181009_01.md 《PostgreSQL 随机记录返回 - 300倍提速实践 (随机数组下标代替order by random())》
201804/20180416_02.md 《PostgreSQL 网约车打车派单 高峰区域集中打车冲突优化1 - 宇宙大爆炸理论与PostgreSQL实践》
201804/20180414_03.md 《网约车打车派单系统思考 数据库设计与实现 - 每月投入6140元, 1天最多可盈利117亿 -_-!》
201712/20171216_01.md 《PostgreSQL 高并发任务分配系统 实践》
201712/20171212_01.md 《阿里云RDS PostgreSQL varbitx实践 - 流式标签 (阅后即焚流式批量计算) - 万亿级,任意标签圈人,毫秒响应》
201711/20171126_01.md 《PostgreSQL手机行业经营分析、决策系统设计 - 实时圈选、透视、估算》
201708/20170803_01.md 《菜鸟末端轨迹 - 电子围栏(解密支撑每天251亿个包裹的数据库) - 阿里云RDS PostgreSQL最佳实践》
201707/20170720_02.md 《云端海量任务调度数据库最佳实践 - 阿里云RDS PostgreSQL案例》
201706/20170619_01.md 《数据库平滑switchover的要素 - 会话资源漂移 - 业务无感、0感知切换探索》
201704/20170424_04.md 《PostgreSQL upsert功能(insert on conflict do)的用法》
201704/20170412_01.md 《快速入门PostgreSQL应用开发与管理 - 6 事务和锁》
201703/20170322_03.md 《数据库三十六计 - PostgreSQL 三十六计(下)》
201701/20170105_08.md 《PostgreSQL 流式数据处理(聚合、过滤、转换...)系列 - 8》
201701/20170105_06.md 《PostgreSQL 流式数据处理(聚合、过滤、转换...)系列 - 6》
201701/20170105_05.md 《PostgreSQL 流式数据处理(聚合、过滤、转换...)系列 - 5》
201701/20170105_04.md 《PostgreSQL 流式数据处理(聚合、过滤、转换...)系列 - 4》
201701/20170105_01.md 《PostgreSQL 流式数据处理(聚合、过滤、转换...)系列 - 1》
201610/20161021_01.md 《基于 阿里云 RDS PostgreSQL 打造实时用户画像推荐系统(varbitx)》
201609/20160926_01.md 《PostgreSQL 数据库开发规范》
201604/20160429_01.md 《[转载]postgresql 9.5版本之前实现upsert功能》
201510/20151008_01.md 《PostgreSQL数据库 OLTP高并发请求性能优化》
相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
15天前
|
数据库
|
2月前
|
关系型数据库 分布式数据库 数据库
开源云原生数据库PolarDB PostgreSQL 15兼容版本正式发布
PolarDB进行了深度的内核优化,从而实现以更低的成本提供商业数据库的性能。
|
3月前
|
SQL 存储 关系型数据库
新手如何入门学习PostgreSQL?
新手如何入门学习PostgreSQL?
|
3月前
|
SQL 存储 关系型数据库
PostgreSQL核心之SQL基础学习
PostgreSQL核心之SQL基础学习
45 3
|
4月前
|
关系型数据库 分布式数据库 数据库
PolarDB产品使用问题之如何进行PostgreSQL(简称PG)的全量和增量备份管理
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
4月前
|
SQL 关系型数据库 Serverless
PolarDB产品使用问题之如何控制队列中排队的SQL的等待时间
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
4月前
|
存储 关系型数据库 分布式数据库
PolarDB产品使用问题之如何查看PolarDB for PostgreSQL的备份信息
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
4月前
|
SQL 存储 关系型数据库
关系型数据库PostgreSQL学习
【7月更文挑战第4天】
456 2
|
4月前
|
设计模式 安全 NoSQL
Java面试题:设计一个线程安全的单例模式,并解释其内存占用和垃圾回收机制;使用生产者消费者模式实现一个并发安全的队列;设计一个支持高并发的分布式锁
Java面试题:设计一个线程安全的单例模式,并解释其内存占用和垃圾回收机制;使用生产者消费者模式实现一个并发安全的队列;设计一个支持高并发的分布式锁
68 0
|
1月前
|
关系型数据库 MySQL 分布式数据库
零基础教你用云数据库PolarDB搭建企业网站,完成就送桌面收纳桶!
零基础教你用云数据库PolarDB搭建企业网站,完成就送桌面收纳桶,邀请好友完成更有机会获得​小米Watch S3、小米体重称​等诸多好礼!
零基础教你用云数据库PolarDB搭建企业网站,完成就送桌面收纳桶!

热门文章

最新文章

相关产品

  • 云原生数据库 PolarDB