高访问量数据库如何避免阻塞 (数据库访问量大 如何阻止阻塞)

数据库是现代软件系统中至关重要的一环。在大多数现代应用程序中,几乎每个子系统都与数据库交互,提供数据存储和处理的核心服务。在这种情况下,数据库的稳定性和可靠性非常关键。如果数据库遇到阻塞,应用程序将会崩溃,从而导致系统停机和数据丢失。这对于任何企业来说都是一场灾难,因此解决阻塞问题非常重要。

为了避免阻塞,我们需要理解发生阻塞的原因以及如何加以预防和解决。

数据库中的阻塞是指在一个事务中发生了某些阻塞操作,而另一个事务无法运行的情况。例如,如果一个事务在读取一个表的某些数据,而另一个事务试图修改该表,则修改事务将被阻塞,直到读取事务完成。

在理想情况下,数据库应该是无阻塞的。但在现实中,很难避免阻塞的发生。可惜的是,一旦阻塞出现,它通常会导致严重的后果。

以下是一些处理高访问量数据库阻塞的实用技巧:

1. 使用合适的索引

索引是优化数据库查询的关键组成部分。如果您的数据库中没有合适的索引,查询可能需要花费很长时间。索引可以在查询过程中快速定位数据,这样查询就会更快,更有效。

2. 分布式架构

分布式架构是防止高访问量数据库阻塞的一种解决方案。在分布式架构中,数据存储在多个节点上,并且每个节点都可以独立地处理查询。这使得每个节点都可以处理自己的负载,从而减少阻塞发生的可能性。

3. 定期维护

定期维护数据库是非常重要的。定期维护包括数据库备份、重建索引、清理垃圾数据等操作。这些操作可以保持数据库的良好状态,并减少阻塞发生的可能性。

4. 避免长时间事务

长时间事务是一种阻塞高发事件。这种情况下,一个事务会持有某个数据库资源,而另一个事务将无法访问该资源,反之亦然。为了避免这种情况的发生,开发人员应该尽量避免设计长时间事务。

5. 资源限制

为了避免阻塞,也可以使用资源限制工具。例如,内存限制可以防止一个事务占用大量内存,而长时间持有该内存。同样地,CPU限制可以防止一个事务使用全部CPU资源,使其他事务无法运行。

阻塞是数据库中比较常见的问题。为了避免阻塞,数据库应该使用合适的索引、分布式架构、定期维护、避免长时间事务和资源限制等技术。在阻塞的发生时,我们需要对其进行分析和解决,以免出现更大的问题。不能够忽略的是,定期升级数据库及其相关组件,及时将数据库和操作系统的安全补丁打上,以保障数据库的安全性。

相关问题拓展阅读:

如何解决数据库数据量大的问题

解决数据库数据量大的问题,分库或者分表都是办法之一。

分库:编程会复杂一些;但是适合更大缺乎量的伏让悉数据库数据量。

分表:数据文件可能还是滑凳偏大。

网站访问量大 怎样优化mysql数据库

I硬件配置优化

CPU选择:多核的CPU,主频高的CPU

内存:更大的内存

磁盘选择:更快的转速、RAID、阵列卡,

网络环境选择:尽量部署在局域网、SCI、光缆、千兆网、双网线和数提供冗余、0.0.0.0多端口绑定监听

II操作系统级优化

使用64位的操作系统,更好的使用大内存扰棚燃。

设置noatime,nodiratime

$ cat /etc/fstab

LABEL=//ext3 defaults,noatime,nodiratime

/dev/sda/dataxfs defaults,noatime,nodiratime

优化内核参数

net.ipv4.tcp_keepalive_time=7200

net.ipv4.tcp_max_syn_backlog=1024

net.ipv4.tcp_syncookies=1

net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_tw_recycle = 1

net.ipv4.neigh.default.gc_thresh3 = 2023

net.ipv4.neigh.default.gc_thresh2 = 1024

net.ipv4.neigh.default.gc_thresh1 = 256

net.ipv4.conf.default.rp_filter = 1

net.ipv4.conf.default.forwarding = 1

net.ipv4.conf.default.proxy_arp = 0

net.ipv4.tcp_syncookies = 1

net.core.netdev_max_backlog = 2023

net.core.dev_weight = 64

net.ipv4.tcp_rmem =777216

net.ipv4.tcp_wmem =777216

net.ipv4.tcp_rfc1337 = 1

net.ipv4.tcp_sack = 0

net.ipv4.tcp_fin_timeout = 20

net.ipv4.tcp_keepalive_probes = 5

net.ipv4.tcp_max_orphans = 32768

net.core.optmem_max = 20230

net.core.rmem_default =

net.core.rmem_max =

net.core.wmem_default =

net.core.wmem_max =

net.core.somaxconn = 500

net.ipv4.tcp_orphan_retries = 1

net.ipv4.tcp_max_tw_buckets = 18000

net.ipv4.ip_forward = 0

net.ipv4.conf.default.proxy_arp = 0

net.ipv4.conf.all.rp_filter = 1

kernel.sysrq = 1

net.ipv4.conf.default.send_redirects = 1

net.ipv4.conf.all.send_redirects = 0

net.ipv4.ip_local_port_range =

kernel.shmmax =

vm.swappiness=0

加大文件描述符限制

Vim /etc/security/limits.conf

加上

*soft nofile

*hard nofile

文件系统选择 xfs

/dev/sda/dataxfs defaults,noatime,nodiratime

III Mysql设计优化

III.1存储引擎的选择

Myisam:数据库并发不大,读多写少,而且都能很好的用缓虚到索引,sql语句比较简单的应用,TB数据仓库

Innodb:并发访问大,写操作比较多,有外键、事务等需求的应用,系统内存较大。

III.2命名规则

多数开发语言命名规则:比如MyAdress

多数开源思想命名规则:my_address

避免随便命名

III.3字段类型选择

字段类型的选择的一般原则:

根据需求选择合适的字段类型,在满足需求的情况下字段类型尽可能小。

只分配满足需求的最小字符数,不要太慷慨。

原因:更小的字段类型更小的字符数占用更少的内存,占用更少的磁盘空间,占用更少的磁盘IO,以及占用更少的带宽。

III.3.1 整型:

见如下图:

类型

字节

最小值

更大值

(带符号的/无符号的)

(带符号的/无符号的)

TINYINT

-128

127

255

ALLINT

-32768

32767

65535

MEDIUMINT

INT

BIGINT

775808

75807

551615

根据满足需求的最小整数为选择原则,能用INT的就不要用BIGINT。

用无符号INT存储IP,而非CHAR(15)。

III.3.2 浮点型:

类型

字节

精度类型

使用场景

FLOAT(M,D)

单精度

精度要求不高,数值比较小

DOUBLE(M,D)(REAL)

双精度

精度要求不高,数值比较大

DECIMAL(M,D)(NUMERIC)

M+2

自定义精度

精度要求很高的场景

III.3.3 时间类型

类型

取值范围

存储空间

零值表示法

DATE

~

3字节

TIME

-838:59:59~838:59:59

3字节

00:00:00

DATETIME

:00:00~:59:59

8字节

:00:00

TIMESTAMP

~2023年的某个时刻

4字节

YEAR

YEAR(4):1901~2155 YEAR(2):1970~2023

1字节

0000

III.3.4 字符类型

类型

更大长度

占用存储空间

CHAR

M字节

M字节

VARCHAR

M字节

M+1字节

TINYBLOD,TINYTEXT

2^8-1字节

L+1字节

BLOB,TEXT

2^16-1字节

L+2

MEDIUMBLOB,MEDIUMTEXT

2^24-1字节

L+3

LONGBLOB,LONGTEXT

2^32-1字节

L+4

ENUM(‘value1′,’value2’,…)

65535个成员

1或2字节

SET(‘value1′,’value2’,…)

64个成员

1,2,3,4或8字节

注:L表示可变长度的意思

对于varchar和char的选择要根据引擎和具体情况的不同来选择,主要依据如下原则:

1. 如果列数据项的大小一致或者相差不大,则使用char。

2. 如果列数据项的大小差异相当大,则使用varchar。

3. 对于MyISAM表,尽量使用Char,对于那些经常需要修改而容易形成碎片的myisam和isam数据表就更是如此,它的缺点就是占用磁盘空间。

4. 对于InnoDB表,因为它的数据行内部存储格式对固定长度的数据行和可变长度的数据行不加区分(所有数据行共用一个表头部分,这个标头部分存放着指向各有关数据列的指针),所以使用char类型不见得会比使用varchar类型好。事实上,因为char类型通常要比varchar类型占用更多的空 间,所以从减少空间占用量和减少磁盘i/o的角度,使用varchar类型反而更有利。

5.表中只要存在一个varchar类型的字段,那么所有的char字段都会自动变成varchar类型,因此建议定长和变长的数据分开。

III.4编码选择

单字节 latin1

多字节 utf8(汉字占3个字节,英文字母占用一个字节)

如果含有中文字符的话更好都统一采用utf8类型,避免乱码的情况发生。

III.5主键选择原则

注:这里说的主键设计主要是针对INNODB引擎

1. 能唯一的表示行。

2. 显式的定义一个数值类型自增字段的主键,这个字段可以仅用于做主键,不做其他用途。

3. MySQL主键应该是单列的,以便提高连接和筛选操作的效率。

4. 主键字段类型尽可能小,能用ALLINT就不用INT,能用INT就不用BIGINT。

5. 尽量保证不对主键字段进行更新修改,防止主键字段发生变化,引发数据存储碎片,降低IO性能。

6. MySQL主键不应包含动态变化的数据,如时间戳、创建时间列、修改时间列等。

7. MySQL主键应当有计算机自动生成。

8. 主键字段放在数据表的之一顺序。

推荐采用数值类型做主键并采用auto_increment属性让其自动增长。

III.6其他需要注意的地方

NULL OR NOT NULL

尽可能设置每个字段为NOT NULL,除非有特殊的需求,原因如下:

1. 使用含有NULL列做索引的话会占用更多的磁盘空间,因为索引NULL列需要而外的空间来保存。

2. 进行比较的时候,程序会更复杂。

3. 含有NULL的列比较特殊,SQL难优化,如果是一个组合索引,那么这个NULL 类型的字段会极大影响整个索引的效率。

索引

索引的缺点:极大地加速了查询,减少扫描和锁定的数据行数。

索引的缺点:占用磁盘空间,减慢了数据更新速度,增加了磁盘IO。

添加索引有如下原则:

1. 选择唯一性索引。

2. 为经常需要排序、分组和联合操作的字段建立索引。

3. 为常作为查询条件的字段建立索引。

4. 限制索引的数据,索引不是越多越好。

5. 尽量使用数据量少的索引,对于大字段可以考虑前缀索引。

6. 删除不再使用或者很少使用的索引。

7. 结合核心SQL优先考虑覆盖索引。

8. 忌用字符串做主键。

反范式设计

适当的使用冗余的反范式设计,以空间换时间有的时候会很高效。

IV Mysql软件优化

开启mysql复制,实现读写分离、负载均衡,将读的负载分摊到多个从服务器上,提高服务器的处理能力。

使用推荐的GA版本,提升性能

利用分区新功能进行大数据的数据拆分

VMysql配置优化

注意:全局参数一经设置,随服务器启动预占用资源。

key_buffer_size参数

mysql索引缓冲,如果是采用myisam的话要重点设置这个参数,根据(key_reads/key_read_requests)判断

innodb_buffer_pool_size参数

INNODB 数据、索引、日志缓冲最重要的引擎参数,根据(hit riatos和FILE I/O)判断

wait_time_out参数

线程连接的超时时间,尽量不要设置很大,推荐10s

max_connections参数

服务器允许的更大连接数,尽量不要设置太大,因为设置太大的话容易导致内存溢出,需要通过如下公式来确定:

SET @k_bytes = 1024;

SET @m_bytes = @k_bytes * 1024;

SET @g_bytes = @m_bytes * 1024;

SELECT

(

@@key_buffer_size + @@query_cache_size + @@tmp_table_size+

@@innodb_buffer_pool_size + @@innodb_additional_mem_pool_size+

@@innodb_log_buffer_size+

@@max_connections *

( @@read_buffer_size + @@read_rnd_buffer_size + @@sort_buffer_size+

@@join_buffer_size + @@binlog_cache_size + @@thread_stack

) )

/ @g_bytes AS MAX_MEMORY_USED_GB;

thread_concurrency参数

线程并发利用数量,(cpu+disk)*2,根据(os中显示的请求队列和tickets)判断

sort_buffer_size参数

获得更快的–ORDER BY,GROUP BY,SELECT DISTINCT,UNION DISTINCT

read_rnd_buffer_size参数

当根据键进行分类操作时获得更快的–ORDER BY

join_buffer_size参数

join连接使用全表扫描连接的缓冲大小,根据select_full_join判断

read_buffer_size参数

全表扫描时为查询预留的缓冲大小,根据select_scan判断

tmp_table_size参数

临时内存表的设置,如果超过设置就会转化成磁盘表,根据参数(created_tmp_disk_tables)判断

innodb_log_file_size参数(默认5M)

记录INNODB引擎的redo log文件,设置较大的值意味着较长的恢复时间。

Ø innodb_flush_method参数(默认fdatasync)

Linux系统可以使用O_DIRECT处理数据文件,避免OS级别的cache,O_DIRECT模式提高数据文件和日志文件的IO提交性能

innodb_flush_log_at_trx_commit(默认1)

表示每秒进行一次log写入cache,并flush log到磁盘。

表示在每次事务提交后执行log写入cache,并flush log到磁盘。

表示在每次事务提交后,执行log数据写入到cache,每秒执行一次flush log到磁盘。

VI Mysql语句级优化

1. 性能查的读语句,在innodb中统计行数,建议另外弄一张统计表,采用myisam,定期做统计.一般的对统计的数据不会要求太精准的情况下适用。

2. 尽量不要在数据库中做运算。

3. 避免负向查询和%前缀模糊查询。

4. 不在索引列做运算或者使用函数。

5. 不要在生产环境程序中使用select * from 的形式查询数据。只查询需要使用的列。

6. 查询尽可能使用limit减少返回的行数,减少数据传输时间和带宽浪费。

7. where子句尽可能对查询列使用函数,因为对查询列使用函数用不到索引。

8. 避免隐式类型转换,例如字符型一定要用’’,数字型一定不要使用’’。

9. 所有的SQL关键词用大写,养成良好的习惯,避免SQL语句重复编译造成系统资源的浪费。

10. 联表查询的时候,记得把小结果集放在前面,遵循小结果集驱动大结果集的原则。

数据库访问量大 如何阻止阻塞的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于数据库访问量大 如何阻止阻塞,高访问量数据库如何避免阻塞,如何解决数据库数据量大的问题,网站访问量大 怎样优化mysql数据库的信息别忘了在本站进行查找喔。


数据运维技术 » 高访问量数据库如何避免阻塞 (数据库访问量大 如何阻止阻塞)