精华内容
下载资源
问答
  • HBase性能优化策略

    千次阅读 2017-11-13 10:20:21
    一 HBase写入性能优化 1.1 是否需要WAL? WAL是否需要同步? WAL机制可以确保数据即使写入缓存的数据丢失了,也可以恢复;另外是为了集群之间的异步复制。默认WAL机制开启,且使用同步机制写入WAL. 我们可以...

    HBase写入通常会遇到两种问题:

    # 写的性能很差

    # 根本写不进去


    一 HBase写入性能优化

    1.1 是否需要写WAL? WAL是否需要同步写?

    WAL机制可以确保数据即使写入缓存的数据丢失了,也可以恢复;另外是为了集群之间的异步复制。默认WAL机制开启,且使用同步机制写入WAL. 我们可以考虑是否需要写入WAL,通常大多数企业业务都会开启,但是对于部分业务可能并不特别关心异常情况下部分数据的丢失,而更关心数据写入吞吐量,不能造成数据队列堵塞。这种场景可以选择关闭WAL写入;或者看能否接受异步写入

    所以应该根据业务关注点在WAL机制和写入吞吐量之间做一个抉择

     

    1.2 PUT是否可以同步批量提交

    HBase分别提供了单条put以及批量put的API接口,使用批量put接口可以减少客户端到RegionServer之间的RPC连接数,提高写入性能。另外需要注意的是,批量put请求要么全部成功返回,要么抛出异常。

    所以建议使用批量PUT写入请求

     

    1.3 PUT是否可以异步批量提交

    业务如果可以接受异常情况下少量数据丢失的话,还可以使用异步批量提交的方式提交请求。提交分为两阶段执行:用户提交写请求之后,数据会写入客户端缓存,并返回用户写入成功;当客户端缓存达到阈值(默认2M)之后批量提交给RegionServer。需要注意的是,在某些情况下客户端异常的情况下缓存数据有可能丢失。

     

    所以在业务可以接受的情况下开启异步批量提交


    1.4 Region数量少于RegionServer数量

    当前集群中表的Region个数如果小于RegionServer个数,可以考虑切分Region并尽可能分布到不同RegionServer来提高系统请求并发度,如果Num(Region of Table) > Num(RegionServer),再增加Region个数效果并不明显

     

    所以在Num(Region of Table) <Num(RegionServer)的场景下切分部分请求负载高的Region并迁移到其他RegionServer

     

    1.5 写入请求是否均衡

    另一个需要考虑的问题是写入请求是否均衡,如果不均衡,一方面会导致系统并发度较低,另一方面也有可能造成部分节点负载很高,进而影响其他业务。分布式系统中特别害怕一个节点负载很高的情况,一个节点负载很高可能会拖慢整个集群,这是因为很多业务会使用Mutli批量提交读写请求,一旦其中一部分请求落到该节点无法得到及时响应,就会导致整个批量请求超时。

     

    所以建议检查Rowkey 预分区策略

     

    1.6 写入的KeyValue数据是否太大

    KeyValue大小对写入性能的影响巨大,一旦遇到写入性能比较差的情况,需要考虑是否由于写入KeyValue数据太大导致。KeyValue大小对写入性能影响曲线图如下:



    KeyValue太大会导致HLog文件写入频繁切换、flush以及compaction频繁触发,写入性能急剧下降。

    如果是大字段scan导致RegionServer宕机,那么客户端在访问的时候对返回结果大小做限制(scan.setMaxResultSize(2*1024*1024)),并且对列数量做限制(scan.setBatch(100))

       

    二 写异常问题

    2.1 MemStore相关的配置是否合理

    以RegionServer级别flush进行解析,HBase设定一旦整个RegionServer上所有Memstore占用内存大小总和大于配置文件中upperlimit时,系统就会执行RegionServer级别flush,flush算法会首先按照Region大小进行排序,再按照该顺序依次进行flush,直至总Memstore大小低至lowerlimit

     

    Region规模与Memstore总大小设置是否合理?如果RegionServer上Region较多,而Memstore总大小设置的很小(JVM设置较小或者upper.limit设置较小),就会触发RegionServer级别flush

     

    列族是否设置过多,通常情况下表列族建议设置在1~3个之间,最好一个。如果设置过多,会导致一个Region中包含很多Memstore,导致更容易触到高水位upperlimit

     

    2.2 Store中HFile数量是否大于配置参数blockingStoreFile

    对于数据写入很快的集群,还需要特别关注一个参数:hbase.hstore.blockingStoreFiles,此参数表示如果当前hstore中文件数大于该值,系统将会强制执行compaction操作进行文件合并,合并的过程会阻塞整个hstore的写入。通常情况下该场景发生在数据写入很快的情况下,在日志中可以发现”Waited 3722ms on a compaction to clean up ‘too many store files“

     

    参数设置是否合理?hbase.hstore.compactionThreshold表示启动compaction的最低阈值,该值不能太大,否则会积累太多文件,一般建议设置为5~8左右。hbase.hstore.blockingStoreFiles默认设置为7,可以适当调大一些。


    展开全文
  • 数据库优化之读写分离

    万次阅读 2016-11-02 15:19:43
    2 一般建议值,大约每秒一次事务的刷新及同步到磁盘,实际只到操作系统的buffer中,操作系统如果断电会导致失误丢失; #因为导数据都是人为参与的过程所以设置为2,让速度最大化完成,如果出错再手动搞一次即可。 ...

    前言
    网站发展的初期,由于没有太多访问量,一般来讲只需要一台服务器就够了,这时候应用软件、数据库、文件等所有资源都在一台服务器上。随着用户量和数据文件的增加,单台服务器的性能达到瓶颈,这时候需要把应用软件、数据库和文件资源单独拆分出来,满足他们对服务器硬件资源的不同需求。比如应用软件更多的需要CPU,数据库对磁盘读写多,需要快速的磁盘和充足的内存。随着业务量的再次增加,这时候需要搭建服务器集群来缓解压力,提升网站的性能,应用服务器通过软件或硬件的方式来实现负载均衡,以此来改善负载压力。数据库服务器则从单台到多台,利用主从,读写分离缓存等技术来打破数据瓶颈。
    全文数据库默认为mysql


    一 优化思路及过程
    数据库的优化顺序要根据网站场景具体分析,通常为以下优化过程
    1、服务器配置优化
    1)服务器硬件升级是所有优化方案的前提,一般来讲SQL本身的执行速度都不会太慢,慢主要是需要从磁盘把结果集读入到内存,比如改动大表时Copying to tmp table on disk这种状态常常占据很大比例时间。所以对于单个数据库,优化的次序一般是RAM、高速硬盘、CPU能力。
    2)大多网站的MySQL是IO密集型的,如果你的MySQL是个CPU密集型的话,那么很可能你的MySQL参数配置需要优化了。针对mysql不同的引擎参数配置优化也有所不同
    INNODB表的优化
    innodb_buffer_pool_size
    主要存放热数据,按照page来存放,page为最小单位,甚至是按段来存放
    建议值: 如果是专用数据库server 建议分到物理内存的50% -- 75% 
    max_heap_table_size,tmp_table_size
    此变量定义了用户可以创建的内存表(memory table)的大小.如果内存临时表超出了限制,MySQL就会自动地把它转化为基于磁盘的表,存储在指定的tmpdir目录下。tmp_table_size 和 max_heap_table_size 大小要一致
    innodb_flush_log_at_trx_commit
    如果在导数据,可能是2天或者3天也没有导完,那么可能是这个参数设置为1的结果导致
    1  为每一次事务进一次刷新到磁盘,安全度高,但是性能最低,经常会导致导数据最慢
    0  每秒钟进一下事务的刷新到磁盘
    2  一般建议值,大约每秒一次事务的刷新及同步到磁盘,实际只写到操作系统的buffer中,操作系统如果断电会导致失误丢失;#因为导数据都是人为参与的过程所以设置为2,让速度最大化完成,如果出错再手动搞一次即可。
    MYISAM表的优化:
    key_buffer_size
    key_buffer_size指定索引缓冲区的大小,它决定索引处理的速度,尤其是索引读的速度。key_buffer_size是对MyISAM表性能影响最大的一个参数,通过检查状态值Key_read_requests和Key_reads,可以知道key_buffer_size设置是否合理。比例key_reads /key_read_requests应该尽可能的低,至少是1:100,1:1000更好

    2、sql和索引的优化
    开启mysql的慢查询,查询是否是某个SQL语句占用过多资源,如果是的话,可以对SQL语句进行优化,比如优化 insert 语句、优化 group by 语句、优化 order by 语句、优化 join 语句等等。

    3、缓存技术
    搭建redis或者memcache做为缓存层,提高数据库读取速度。

    4、主从备份读写分离
    读写分离既可以通过代码程序实现,也能利用第三方工具做,提高系统负载能力。

    5、数据的垂直拆分
    垂直拆分,其实就是根据你模块的耦合度,将一个大的系统分为多个小的系统,也就是分布式系统。

    6、数据的水平拆分
    将某个访问极其频繁的表再按照某个字段的某种规则来分散到多个表之中,每个表中包含一部分数据。

    以上就是大多情况下数据库的优化顺序,读写分离是数据库优化的必经之路,所以在这里我们了解一下读写分离的功能、使用场景和一些配置。

    二 读写分离概述
    读写分离从字面意思就可以理解,就是把对数据库的读操作和写操作分离开。读写分离在网站发展初期可以一定程度上缓解读写并发时产生锁的问题,将读写压力分担到多台服务器上,通常用于读远大于写的场景。

    *读写分离的好处*
    1)数据是网站的生命,读写分离通过主从备份数据,保证了系统的冗余,保护了珍贵的数据。
    2)提高了系统性能,一定程度提高了数据库负载能力。

    *适用读写分离场景*
    1)网站初期想要缓解数据负载最简单可行的方案。
    2)服务器面对的是读远大于写的场景,并且业务能够允许时间上一些延迟。

    *读写分离实现方式*
    目前读写分离方案网上找了几个并做了对比。
    1.mycat 基于阿里的cobar改版的(比较稳定,论坛活跃)
    2.atlas 360开发的 网友说不是很稳定 (已经很久没更新)
    3.mysql-proxy mysql自带 (不是很稳定)
    4.oneproxy 比较稳定 性能也很好 (需要付费)
    5.amoeba 好像还行,有一些公司使用 (但是很久没有更新了)

    三 mycat读写分离配置
    综上所述,我选择用mycat来实现mysql的读写分离。
     
    上图的设计思路是这样的
    1.当master正常时,读操作发生在两个slave上,写操作发生在master上。master通过主从配置实时同步数据到两个slave上。
    2.当master挂了,为了数据的一致性,和master为主从关系的slave2被停止访问。这时slave1负责读和写,当master重新恢复后,slave1同步数据给master,然后再次恢复最初读写状态。


     
    为了实现上述思路,我们需要配置mysql的主从备份和主主备份,这个很简单,这里就不叙述了。
    Mycat的前期工作需要Java环境,ubuntu下直接apt-get就可以下载,网上教程很多,下载好java之后再配置一下jdk环境变量
    Whereis  jvm  查看jvm路径
    然后 vi /etc/profile
    export JAVA_HOME=/usr/lib/jvm/java-1.7.0-openjdk-amd64  
    export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$CLASSPATH  
    export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH  
     
    接着 source /etc/profile 使配置生效
    配置好jdk环境变量后就可以下载mycat了
    在mycat 官网就可以下载各种版本,我下载的是Mycat-server-1.5-release版本
     
    Mycat的配置文件主要是conf下的schema.xml,rule.xml,server.xml。
     
    我只是简单的配置了mysql的读写分离,分片分库这些功能并没有使用,所以我只配置了schema.xml和server.xml这两个文件
     
    Server.xml 文件是mycat的登录信息,我修改了以下配置
     <user name="test">   mycat登录用户名
                    <property name="password">test</property>mycat登录密码  
                    <property name="schemas">test,test1(有多个数据库可以添加多个逻辑库)</property>  
            </user>                                           
                                                                                                                                                   
            <user name="user">
                    <property name="password">user</property>
                    <property name="schemas">test</property>
                    <property name="readOnly">true</property>
            </user>
     
     
    Schema.xml 文件里有mycat分库分片和读写分离的配置
    <?xml version="1.0"?>
    <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
    <mycat:schema xmlns:mycat="http://org.opencloudb/" >
     
            <schema name="test" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">    这里的test名字要和server里的一致
           <schema name="test1" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn2">
         
            <dataNode name="dn1" dataHost="localhost1" database="test" />
            <dataNode name="dn2" dataHost="localhost1" database="test1" />
         
            <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
                    writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                    <heartbeat>select user()</heartbeat>
                   
                    <writeHost host="hostM1" url="localhost:3306" user="root"
                            password="">
                       </writeHost>
                    <writeHost host="hostS1" url="192.168.1.1:3306" user="root"
                            password="" />
                  
            </dataHost>
            
    </mycat:schema>
     
     这里我把注释文件全都删除了,因为我只需要实现读写分离,所以配置比较简单。
     这里需要注意的是 balance, switchType, writeType

    balance="0", 不开启读写分离机制,所有读操作都发送到当前可用的writeHost上。
    balance="1",全部的readHost与stand by writeHost参与select语句的负载均衡,简单的说,当双主双从模式(M1->S1,M2->S2,并且M1与M2互为主备),正常情况下,M2,S1,S2都参与select语句的负载均衡。
    balance="2",所有读操作都随机的在writeHost、readhost上分发。
    balance="3",所有读请求随机的分发到wiriterHost对应的readhost执行,writerHost不负担读压力
    writeType表示写模式
    writeType="0",所有的操作发送到配置的第一个writehost
    writeType="1",随机发送到配置的所有writehost
    writeType="2",不执行写操作
    switchType指的是切换的模式,目前的取值也有4种:
    switchType=‘-1‘ 表示不自动切换
    switchType=‘1‘ 默认值,表示自动切换
    switchType=‘2‘ 基于MySQL主从同步的状态决定是否切换,心跳语句为show slave status
    switchType=‘3‘基于MySQL galary cluster的切换机制(适合集群)(1.4.1),心跳语句为show status like ‘wsrep%‘。
    我上面的配置是实现的两个mysql都参与读操作,写操作只在hostm上进行,当hostm挂掉之后在hosts上进行。
     
    完成后进入bin文件,./mycat start 启动mycat
     
    如果只是实现读写分离,mycat的配置文件还是比较简单的,不过有几点需要注意。
     
    1)确定上面mysql用户是否有远程登录的权限
    2)mycat有两个端口,一个是8066,一个是9066,其中9066是管理端口,8066是数据端口,我之前一直登录管理端口,show  tables;时不能成功执行,后来才发现登录8066才行。

    遇到的问题和总结
    1)在优化的过程中,通过给予合适的mysql参数配置解决了数据库cpu密集,假死的问题。
    2)mycat读写分离架构中读数据库使用myisam引擎,然而myisam引擎面对长查询和复杂查询不能体现出优越的查询速度。所以使用myisam引擎作为读服务器还有待继续考虑。
    3)至此,mycat读写分离就配置完成了,不过以上的架构还有一个mycat单点问题,可以通过LVS+Keepalived搭建MYCAT的高可用负载集群。读写分离只是负载了读写的压力,如果想再次提升数据库的性能就要进行数据垂直和水平拆分的操作了。










    展开全文
  • WPF 性能优化建议

    千次阅读 2019-04-12 10:10:25
    本章讲述:WPF 性能优化建议 20180930 WPF性能优化问题:运行软件发现CPU使用率很大(80%-95%),程序中含有委托,线程,定时器的处理,之前优化时,主要优化线程和定时器相关线程方面的处理,但是效果甚微; 无意...

    本章讲述:WPF 性能优化建议

    20180930 WPF性能优化问题:运行软件发现CPU使用率很大(80%-95%),程序中含有委托,线程,定时器的处理,之前优化时,主要优化线程和定时器相关线程方面的处理,但是效果甚微;

    无意间看到博客中说程序界面中使用了投影效果会造成CPU使用率高,就试着修改,没想到,软件运行稳定后CPU使用率下降到了30%左右。

    现整理一下WPF性能优化建议:

    1、尽量不使用DropShadowEffect投影效果,消耗资源很大;

    2、在自定义控件,尽量不要在控件的ResourceDictionary定义资源,而应该放在Window或者Application级。因为放在控件中会使每个实例都保留一份资源的拷贝;

    3、尽量多使用Canvas等简单的布局元素,少使用Grid或者StackPanel等复杂的,减小开销;

    4、少用Margin Padding尤其避免嵌套使用;

    5、尽量使用Static Resources不用DynamicResource;

    6、计时尽量使用DispatcherTimer替代Timer;

    7、自定义控件尽量从轻量级的控件继承;

    8、需要绑定的属性设置为DependencyProperty的依赖项属性效率要高很多,不要自己写继承自INotifyPropertyChanged的属性:http://www.codeproject.com/Articles/62158/DependencyProperties-or-INotifyPropertyChanged

    9、文字少的时候用TextBlock或者label,长的时候用FlowDocument;

    10、绑定的字符串用Textblock;不用label;

    11、如果正在绘制的内容需要频繁地重新绘制,考虑设置各Uelement对象的CacheMode="BitmapCache";

    12、避免使用 Run 来设置文本属性:(MSDN)

       <TextBlock>
          <Run FontWeight="Bold">Hello, world</Run>
        </TextBlock>
        <TextBlock FontWeight="Bold">
          Hello, world
        </TextBlock>

    13、尽量不要过分依赖使用值转换器;尽量少使用第三方类库;尽量不要设置控件Opacity属性,而用Visibility

    14、加快WPF程序的启动速度:

        (1).减少需要显示的元素数量,去除不需要或者冗余的XAML元素代码.

        (2).使用UI虚拟化,只显示当前需要显示的元素.

        (3).不要把不要显示的自定义控件隐藏在主界面中,虽然它们不会显示出来,但是程序启动时还是会去计算自定义控件所需的空间和位置.

    15、 耗时操作放在放在非UI线程上处理,保持UI的顺畅。处理完成后如果需要在UI上展示,调用Dispatcher.BeginInoke()方法。更多内容参考WPF QuickStart系列之线程模型(Thread Model);

    16、关于Data Binding,根据实际情况对Binding指定不同的Mode,性能OneWay优于TwoWay。另外修正掉系统中Binding错误,可以在Visual Studio的输出日志中查找System.Windows.Data Error;

    17、Resources: 系统资源,通常情况下我们会把样式资源都统一到App.xaml中,这是很好的,便于资源的管理。不过尽量把多次重复用到的资源放到App.xaml中。例如某些页面的资源只会在当前页面中使用到,那么可以把资源定义在当前页面; 如非必要,不要使用DynaicResource,使用StaticResource即可;

    18、对Item类型控件重写时,使用VirtualizingStackPanel作为ItemPanel,这样列表资源可以只渲染当前需要的内容。不过如果设置CanContextScrol="True"会阻止虚拟化,另外使用VirtualizingStackPanel时,可以设置VirtualizingStackPanel.VirtualizationMode="Recycling", 这样已经显示过的列表不会被重复创建和释放掉。

    19、尽量少的使用Animation,尤其在程序启动时,Animation渲染时会占用一些CPU资源。

    展开全文
  • 如何优化MySQL千万级大表,我了6000字的解读

    万次阅读 多人点赞 2019-10-21 20:03:03
    千万级大表如何优化,这是一个很有技术含量的问题,通常我们的直觉思维都会跳转到拆分或者数据分区,在此我想做一些补充和梳理,想和大家做一些这方面的经验总结,也欢迎大家提出建议。 从一开始脑海里开始也是...
        

    这是学习笔记的第 2138 篇文章

      640?wx_fmt=gif

    千万级大表如何优化,这是一个很有技术含量的问题,通常我们的直觉思维都会跳转到拆分或者数据分区,在此我想做一些补充和梳理,想和大家做一些这方面的经验总结,也欢迎大家提出建议。 

    从一开始脑海里开始也是火光四现,到不断的自我批评,后来也参考了一些团队的经验,我整理了下面的大纲内容。

    640?wx_fmt=png

    既然要吃透这个问题,我们势必要回到本源,我把这个问题分为三部分:

    “千万级”,“大表”,“优化”,

    也分别对应我们在图中标识的

    “数据量”,“对象”和“目标”。

    我来逐步展开说明一下,从而给出一系列的解决方案。 

    1.数据量:千万级

    千万级其实只是一个感官的数字,就是我们印象中的数据量大。 这里我们需要把这个概念细化,因为随着业务和时间的变化,数据量也会有变化,我们应该是带着一种动态思维来审视这个指标,从而对于不同的场景我们应该有不同的处理策略。

     

    1) 数据量为千万级,可能达到亿级或者更高

    通常是一些数据流水,日志记录的业务,里面的数据随着时间的增长会逐步增多,超过千万门槛是很容易的一件事情。

    2) 数据量为千万级,是一个相对稳定的数据量

    如果数据量相对稳定,通常是在一些偏向于状态的数据,比如有1000万用户,那么这些用户的信息在表中都有相应的一行数据记录,随着业务的增长,这个量级相对是比较稳定的。

    3) 数据量为千万级,不应该有这么多的数据

    这种情况是我们被动发现的居多,通常发现的时候已经晚了,比如你看到一个配置表,数据量上千万;或者说一些表里的数据已经存储了很久,99%的数据都属于过期数据或者垃圾数据。

    数据量是一个整体的认识,我们需要对数据做更近一层的理解,这就可以引出第二个部分的内容。 

    2.对象:数据表

    数据操作的过程就好比数据库中存在着多条管道,这些管道中都流淌着要处理的数据,这些数据的用处和归属是不一样的。

    一般根据业务类型把数据分为三种:

    (1)流水型数据

    流水型数据是无状态的,多笔业务之间没有关联,每次业务过来的时候都会产生新的单据,比如交易流水、支付流水,只要能插入新单据就能完成业务,特点是后面的数据不依赖前面的数据,所有的数据按时间流水进入数据库。

    (2)状态型数据

    状态型数据是有状态的,多笔业务之间依赖于有状态的数据,而且要保证该数据的准确性,比如充值时必须要拿到原来的余额,才能支付成功。

    (3)配置型数据

    此类型数据数据量较小,而且结构简单,一般为静态数据,变化频率很低。

    至此,我们可以对整体的背景有一个认识了,如果要做优化,其实要面对的是这样的3*3的矩阵,如果要考虑表的读写比例(读多写少,读少写多...),那么就会是3*3*4=24种,显然做穷举是不显示的,而且也完全没有必要,可以针对不同的数据存储特性和业务特点来指定不同的业务策略。 

    对此我们采取抓住重点的方式,把常见的一些优化思路梳理出来,尤其是里面的核心思想,也是我们整个优化设计的一把尺子,而难度决定了我们做这件事情的动力和风险。

    数据量增长情况

    数据表类型

    业务特点

    优化核心思想

    优化难度

    数据量为千万级,是一个相对稳定的数据量

    状态表

    OLTP业务方向

    能不拆就不拆读需求水平扩展

    ****

    数据量为千万级,可能达到亿级或者更高

    流水表

    OLTP业务的历史记录

    业务拆分,面向分布式存储设计

    ****

    OLAP业务统计数据源

    设计数据统计需求存储的分布式扩展

    ***

    数据量为千万级,不应该有这么多的数据

    配置表

    通用业务

    小而简,避免大一统

    *

    而对于优化方案,我想采用面向业务的维度来进行阐述。 

    3.目标:优化

    在这个阶段,我们要说优化的方案了,总结的有点多,相对来说是比较全了。

    整体分为五个部分:

    640?wx_fmt=png

    其实我们通常所说的分库分表等方案只是其中的一小部分,如果展开之后就比较丰富了。

    640?wx_fmt=png

    其实不难理解,我们要支撑的表数据量是千万级别,相对来说是比较大了,DBA要维护的表肯定不止一张,如何能够更好的管理,同时在业务发展中能够支撑扩展,同时保证性能,这是摆在我们面前的几座大山。

    我们分别来说一下这五类改进方案:

    优化设计方案1.规范设计

    在此我们先提到的是规范设计,而不是其他高大上的设计方案。

    黑格尔说:秩序是自由的第一条件。在分工协作的工作场景中尤其重要,否则团队之间互相牵制太多,问题多多。

    规范设计我想提到如下的几个规范,其实只是属于开发规范的一部分内容,可以作为参考。

    640?wx_fmt=png

    规范的本质不是解决问题,而是有效杜绝一些潜在问题,对于千万级大表要遵守的规范,我梳理了如下的一些细则,基本可以涵盖我们常见的一些设计和使用问题,比如表的字段设计不管三七二十一,都是varchar(500),其实是很不规范的一种实现方式,我们来展开说一下这几个规范。

    1)配置规范

    (1)MySQL数据库默认使用InnoDB存储引擎。

    (2)保证字符集设置统一,MySQL数据库相关系统、数据库、表的字符集使都用UTF8,应用程序连接、展示等可以设置字符集的地方也都统一设置为UTF8字符集。

    注:UTF8格式是存储不了表情类数据,需要使用UTF8MB4,可在MySQL字符集里面设置。在8.0中已经默认为UTF8MB4,可以根据公司的业务情况进行统一或者定制化设置。

    (3)MySQL数据库的事务隔离级别默认为RR(Repeatable-Read),建议初始化时统一设置为RC(Read-Committed),对于OLTP业务更适合。

    (4)数据库中的表要合理规划,控制单表数据量,对于MySQL数据库来说,建议单表记录数控制在2000W以内。

    (5)MySQL实例下,数据库、表数量尽可能少;数据库一般不超过50个,每个数据库下,数据表数量一般不超过500个(包括分区表)。

    2)建表规范

    (1)InnoDB禁止使用外键约束,可以通过程序层面保证。

    (2)存储精确浮点数必须使用DECIMAL替代FLOAT和DOUBLE。

    (3)整型定义中无需定义显示宽度,比如:使用INT,而不是INT(4)。

    (4)不建议使用ENUM类型,可使用TINYINT来代替。

    (5)尽可能不使用TEXT、BLOB类型,如果必须使用,建议将过大字段或是不常用的描述型较大字段拆分到其他表中;另外,禁止用数据库存储图片或文件。

    (6)存储年时使用YEAR(4),不使用YEAR(2)。

    (7)建议字段定义为NOT NULL。

    (8)建议DBA提供SQL审核工具,建表规范性需要通过审核工具审核后

    3)命名规范

    (1)库、表、字段全部采用小写。

    (2)库名、表名、字段名、索引名称均使用小写字母,并以“_”分割。

    (3)库名、表名、字段名建议不超过12个字符。(库名、表名、字段名支持最多64个字符,但为了统一规范、易于辨识以及减少传输量,统一不超过12字符)

    (4)库名、表名、字段名见名知意,不需要添加注释。

    对于对象命名规范的一个简要总结如下表4-1所示,供参考。

    命名列表

    对象中文名称

    对象英文全称

    MySQL对象简写

    视图

    view

    view_

    函数

    function

    func_

    存储过程

    procedure

    proc_

    触发器

    trigger

    trig_

    普通索引

    index

    idx_

    唯一索引

    unique index

    uniq_

    主键索引

    primary key

    pk_

    4)索引规范

    (1)索引建议命名规则:idx_col1_col2[_colN]、uniq_col1_col2[_colN](如果字段过长建议采用缩写)。

    (2)索引中的字段数建议不超过5个。

    (3)单张表的索引个数控制在5个以内。

    (4)InnoDB表一般都建议有主键列,尤其在高可用集群方案中是作为必须项的。

    (5)建立复合索引时,优先将选择性高的字段放在前面。

    (6)UPDATE、DELETE语句需要根据WHERE条件添加索引。

    (7)不建议使用%前缀模糊查询,例如LIKE “%weibo”,无法用到索引,会导致全表扫描。

    (8)合理利用覆盖索引,例如:

    (9)SELECT email,uid FROM user_email WHERE uid=xx,如果uid不是主键,可以创建覆盖索引idx_uid_email(uid,email)来提高查询效率。

    (10)避免在索引字段上使用函数,否则会导致查询时索引失效。

    (11)确认索引是否需要变更时要联系DBA。

    5)应用规范

    (1)避免使用存储过程、触发器、自定义函数等,容易将业务逻辑和DB耦合在一起,后期做分布式方案时会成为瓶颈。

    (2)考虑使用UNION ALL,减少使用UNION,因为UNION ALL不去重,而少了排序操作,速度相对比UNION要快,如果没有去重的需求,优先使用UNION ALL。

    (3)考虑使用limit N,少用limit M,N,特别是大表或M比较大的时候。

    (4)减少或避免排序,如:group by语句中如果不需要排序,可以增加order by null。

    (5)统计表中记录数时使用COUNT(*),而不是COUNT(primary_key)和COUNT(1);InnoDB表避免使用COUNT(*)操作,计数统计实时要求较强可以使用Memcache或者Redis,非实时统计可以使用单独统计表,定时更新。

    (6)做字段变更操作(modify column/change column)的时候必须加上原有的注释属性,否则修改后,注释会丢失。

    (7)使用prepared statement可以提高性能并且避免SQL注入。

    (8)SQL语句中IN包含的值不应过多。

    (9)UPDATE、DELETE语句一定要有明确的WHERE条件。

    (10)WHERE条件中的字段值需要符合该字段的数据类型,避免MySQL进行隐式类型转化。

    (11)SELECT、INSERT语句必须显式的指明字段名称,禁止使用SELECT * 或是INSERT INTO table_name values()。

    (12)INSERT语句使用batch提交(INSERT INTO table_name VALUES(),(),()……),values的个数不应过多。

    优化设计方案2:业务层优化

    业务层优化应该是收益最高的优化方式了,而且对于业务层完全可见,主要有业务拆分,数据拆分和两类常见的优化场景(读多写少,读少写多)

    640?wx_fmt=png

    1)业务拆分

    ü 将混合业务拆分为独立业务

    ü 将状态和历史数据分离

    业务拆分其实是把一个混合的业务剥离成为更加清晰的独立业务,这样业务1,业务2。。。独立的业务使得业务总量依旧很大,但是每个部分都是相对独立的,可靠性依然有保证。

    对于状态和历史数据分离,我可以举一个例子来说明。

    例如:我们有一张表Account,假设用户余额为100。

    640?wx_fmt=png

    我们需要在发生数据变更后,能够追溯数据变更的历史信息,如果对账户更新状态数据,增加100的余额,这样余额为200。

    这个过程可能对应一条update语句,一条insert语句。

    对此我们可以改造为两个不同的数据源,account和account_hist

    在account_hist中就会是两条insert记录,如下:

    640?wx_fmt=png

    而在account中则是一条update语句,如下:

    640?wx_fmt=png

    这也是一种很基础的冷热分离,可以大大减少维护的复杂度,提高业务响应效率。

    2)数据拆分

    2.1 按照日期拆分,这种使用方式比较普遍,尤其是按照日期维度的拆分,其实在程序层面的改动很小,但是扩展性方面的收益很大。

    • 数据按照日期维度拆分,如test_20191021

    • 数据按照周月为维度拆分,test_201910

    • 数据按照季度,年维度拆分,test_2019

    2.2 采用分区模式,分区模式也是常见的使用方式,采用hash,range等方式会多一些,在MySQL中我是不大建议使用分区表的使用方式,因为随着存储容量的增长,数据虽然做了垂直拆分,但是归根结底,数据其实难以实现水平扩展,在MySQL中是有更好的扩展方式。

    2.3 读多写少优化场景

    采用缓存,采用Redis技术,将读请求打在缓存层面,这样可以大大降低MySQL层面的热点数据查询压力。

    2.4 读少写多优化场景,可以采用三步走:

    1) 采用异步提交模式,异步对于应用层来说最直观的就是性能的提升,产生最少的同步等待。

    2) 使用队列技术,大量的写请求可以通过队列的方式来进行扩展,实现批量的数据写入。

    3) 降低写入频率,这个比较难理解,我举个例子

    对于业务数据,比如积分类,相比于金额来说业务优先级略低的场景,如果数据的更新过于频繁,可以适度调整数据更新的范围(比如从原来的每分钟调整为10分钟)来减少更新的频率。

    例如:更新状态数据,积分为200,如下图所示

    640?wx_fmt=png

    可以改造为,如下图所示。

    640?wx_fmt=png

    如果业务数据在短时间内更新过于频繁,比如1分钟更新100次,积分从100到10000,则可以根据时间频率批量提交。

    例如:更新状态数据,积分为100,如下图所示。

    640?wx_fmt=png

    无需生成100个事务(200SQL语句)可以改造为2SQL语句,如下图所示。

    640?wx_fmt=png

    对于业务指标,比如更新频率细节信息,可以根据具体业务场景来讨论决定。

    优化设计方案3:架构层优化

    架构层优化其实就是我们认为的那种技术含量很高的工作,我们需要根据业务场景在架构层面引入一些新的花样来。

    640?wx_fmt=png

    3.1.系统水平扩展场景

    3.1.1采用中间件技术,可以实现数据路由,水平扩展,常见的中间件有MyCATShardingSphere,ProxySQL等

    640?wx_fmt=jpeg

    3.1.2 采用读写分离技术,这是针对读需求的扩展,更侧重于状态表,在允许一定延迟的情况下,可以采用多副本的模式实现读需求的水平扩展,也可以采用中间件来实现,如MyCAT,ProxySQL,MaxScale,MySQL Router

    640?wx_fmt=png

    3.1.3 采用负载均衡技术,常见的有LVS技术或者基于域名服务的Consul技术

    3.2.兼顾OLTP+OLAP的业务场景,可以采用NewSQL,优先兼容MySQL协议的HTAP技术栈,如TiDB

    3.3.离线统计的业务场景,有几类方案可供选择。

    3.3.1 采用NoSQL体系,主要有两类,一类是适合兼容MySQL协议的数据仓库体系,常见的有Infobright或者ColumnStore,另外一类是基于列式存储,属于异构方向,如HBase技术

    3.3.2 采用数仓体系,基于MPP架构,如使用Greenplum统计,如T+1统计

    优化设计方案4:数据库优化

    数据库优化,其实可打的牌也不少,但是相对来说空间没有那么大了,我们来逐个说一下。

    640?wx_fmt=png

    4.1 事务优化

    根据业务场景选择事务模型,是否是强事务依赖

    对于事务降维策略,我们来举出几个小例子来。

    4.1.1 降维策略1:存储过程调用转换为透明的SQL调用

    对于新业务而言,使用存储过程显然不是一个好主意,MySQL的存储过程和其他商业数据库相比,功能和性能都有待验证,而且在目前轻量化的业务处理中,存储过程的处理方式太“重”了。

    有些应用架构看起来是按照分布式部署的,但在数据库层的调用方式是基于存储过程,因为存储过程封装了大量的逻辑,难以调试,而且移植性不高,这样业务逻辑和性能压力都在数据库层面了,使得数据库层很容易成为瓶颈,而且难以实现真正的分布式。

    所以有一个明确的改进方向就是对于存储过程的改造,把它改造为SQL调用的方式,可以极大地提高业务的处理效率,在数据库的接口调用上足够简单而且清晰可控。

    4.1.2 降维策略2DDL操作转换为DML操作

    有些业务经常会有一种紧急需求,总是需要给一个表添加字段,搞得DBA和业务同学都挺累,可以想象一个表有上百个字段,而且基本都是name1,name2……name100,这种设计本身就是有问题的,更不用考虑性能了。究其原因,是因为业务的需求动态变化,比如一个游戏装备有20个属性,可能过了一个月之后就增加到了40个属性,这样一来,所有的装备都有40个属性,不管用没用到,而且这种方式也存在诸多的冗余。

    我们在设计规范里面也提到了一些设计的基本要素,在这些基础上需要补充的是,保持有限的字段,如果要实现这些功能的扩展,其实完全可以通过配置化的方式来实现,比如把一些动态添加的字段转换为一些配置信息。配置信息可以通过DML的方式进行修改和补充,对于数据入口也可以更加动态、易扩展。

    4.1.3 降维策略3:Delete操作转换为高效操作

    有些业务需要定期来清理一些周期性数据,比如表里的数据只保留一个月,那么超出时间范围的数据就要清理掉了,而如果表的量级比较大的情况下,这种Delete操作的代价实在太高,我们可以有两类解决方案来把Delete操作转换为更为高效的方式。 

    第一种是根据业务建立周期表,比如按照月表、周表、日表等维度来设计,这样数据的清理就是一个相对可控而且高效的方式了。 

    第二种方案是使用MySQL rename的操作方式,比如一张2千万的大表要清理99%的数据,那么需要保留的1%的数据我们可以很快根据条件过滤补录,实现“移形换位”。

    4.2 SQL优化

    其实相对来说需要的极简的设计,很多点都在规范设计里面了,如果遵守规范,八九不离十的问题都会杜绝掉,在此补充几点:

    4.2.1 SQL语句简化,简化是SQL优化的一大利器,因为简单,所以优越。

    4.2.2 尽可能避免或者杜绝多表复杂关联,大表关联是大表处理的噩梦,一旦打开了这个口子,越来越多的需求需要关联,性能优化就没有回头路了,更何况大表关联是MySQL的弱项,尽管Hash Join才推出,不要像掌握了绝对大杀器一样,在商业数据库中早就存在,问题照样层出不穷。

    4.2.3 SQL中尽可能避免反连接,避免半连接,这是优化器做得薄弱的一方面,什么是反连接,半连接?其实比较好理解,举个例子,not in ,not exists就是反连接,in,exists就是半连接,在千万级大表中出现这种问题,性能是几个数量级的差异。 

    4.3 索引优化

    应该是大表优化中需要把握的一个度。

    4.3.1 首先必须有主键,规范设计中第一条就是,此处不接收反驳。

    4.3.2 其次,SQL查询基于索引或者唯一性索引,使得查询模型尽可能简单。

    4.3.3 最后,尽可能杜绝范围数据的查询,范围扫描在千万级大表情况下还是尽可能减少。

    优化设计方案4:管理优化

    这部分应该是在所有的解决方案中最容易被忽视的部分了,我放在最后,在此也向运维同事致敬,总是为很多认为本应该正常的问题尽职尽责(背锅)。

    640?wx_fmt=png

    千万级大表的数据清理一般来说是比较耗时的,在此建议在设计中需要完善冷热数据分离的策略,可能听起来比较拗口,我来举一个例子,把大表的Drop 操作转换为可逆的DDL操作。

    Drop操作是默认提交的,而且是不可逆的,在数据库操作中都是跑路的代名词,MySQL层面目前没有相应的Drop操作恢复功能,除非通过备份来恢复,但是我们可以考虑将Drop操作转换为一种可逆的DDL操作。

    MySQL中默认每个表有一个对应的ibd文件,其实可以把Drop操作转换为一个rename操作,即把文件从testdb迁移到testdb_arch下面;从权限上来说,testdb_arch是业务不可见的,rename操作可以平滑的实现这个删除功能,如果在一定时间后确认可以清理,则数据清理对于已有的业务流程是不可见的,如下图所示。

    640?wx_fmt=png

    此外,还有两个额外建议,一个是对于大表变更,尽可能考虑低峰时段的在线变更,比如使用pt-osc工具或者是维护时段的变更,就不再赘述了。

    最后总结一下,其实就是一句话:

    千万级大表的优化是根据业务场景,以成本为代价进行优化的,绝对不是孤立的一个层面的优化

    近期热文:

    个人新书 《MySQL DBA工作笔记》

    个人公众号:jianrong-notes

    QQ群号:763628645

    QQ群二维码如下,个人微信号:jeanron100, 添加请注明:姓名+地区+职位,否则不予通过

    640?wx_fmt=png640?wx_fmt=png

    在看,让更多人看到

    展开全文
  • MySQL优化建议

    千次阅读 多人点赞 2020-12-25 08:28:32
    仅个人总结,欢迎一起交流! MySQL优化的本质: ...以下为本人总结的部分优化建议: 选择InnoDB引擎。InnoDB引擎支持事务、行级锁、并发性能更好,CPU及内存缓存页优化使得资源利用率更高。 .
  • excel文件性能优化

    千次阅读 2018-02-23 10:25:46
    一个5W行, 每行10列的excel文件 测试机器 :MacBook Pro, i7 标压4系, 16G内存 1. 用XSSFWorkbook生成excel文件 a. 测试代码 /** * @auther * @date 2018/2/9 **/ public class ...
  • sql优化建议

    千次阅读 热门讨论 2016-07-25 15:31:18
    我们经常在一起讨论存储过程或者是sql性能优化的事情来降低应用运行时的时间,提高性能,经过和数据库方面的工程师的一些讨论与学习,收获了一些对优化sql比较有帮助的几点建议,同时在应用开发的实践中,证实的确...
  • 人工智能的本质就是最优化。假设把任务比作是一碗饭, 传统的解决方法,就是根据数学公式,然后一口气吃完饭,如果饭碗小,数学公式还行,如果饭碗大,数学公式能一口吃完饭吗? 人工智能的本质就是有很多优化算法,...
  • TDK是什么意思,TDK怎么?SEO中的TDK分别代表标题,关键词,描述,那么对于TDK如何能提高网站关键词排名呢?一个好的TDK充分证明该...下面yetaoaiueo跟大家说说SEO中的TDK是什么意思,怎么利于SEO优化?   ...
  • unity几种优化建议

    千次阅读 2016-10-14 16:28:20
    最简单的优化建议: 1.PC平台的话保持场景中显示的顶点数少于200K~3M,移动设备的话少于10W,一切取决于你的目标GPU与CPU。 2.如果你用U3D自带的SHADER,在表现不差的情况下选择Mobile或Unlit目录下的。它们更...
  • Oracle:SQL优化建议

    千次阅读 2018-06-14 13:49:34
    Oracle:SQL优化建议 下述为34条Oracle中SQL的优化建议,仅供参考。 (1)选择最有效率的表名顺序(只在基于规则的优化器中有效): ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中在最后的...
  • Hbase高并发读写优化

    万次阅读 2015-03-24 19:41:04
    在作了较多优化改进后发现仍有几个worker比较慢,跟踪那几个慢的worker日志发现读HBase经常超时,找到超时的region server,从HMaster UI上观察到这个server的读写请求数明显是其它server的好几倍。开始怀疑是数据有...
  • Oracle SQL优化建议

    千次阅读 2012-10-25 09:12:40
    Oracle SQL优化建议 (2010-09-09 11:54) 分类: 性能调优 SQL优化: 固定的SQL书写习惯,相同的查询尽量保持相同,存储过程的效率较高。 应该编写与其格式一致的语句,包括字母的大小、标点符号...
  • 前言 最近项目的数据库要从oracle转PG,基于开源以及普及度方面PG不及mysql,基于性能不及Oracle,这样选型PG的用意何在呢?所以,趁着这个空档是时间来了解...的《数据库查询优化器的艺术》 这本书的一些心得体...
  • HBase最佳实践-性能优化策略

    千次阅读 2017-03-19 21:12:57
    上一篇文章主要介绍了HBase读性能优化的基本套路,本篇文章来说道说道如何诊断HBase数据的异常问题以及优化写性能。和读相比,HBase数据流程倒是显得很简单:数据先顺序写入HLog,再写入对应的缓存Memstore,当...
  • 上一篇文章主要介绍了HBase读性能优化的基本套路,本篇文章来说道说道如何诊断HBase数据的异常问题以及优化写性能。和读相比,HBase数据流程倒是显得很简单:数据先顺序写入HLog,再写入对应的缓存Memstore,当...
  • SQL优化建议30条

    千次阅读 2019-02-27 13:30:36
    1、对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。 2、应尽量避免在 where 子句中使用!=或&lt;&gt;操作符,否则将引擎放弃使用索引而进行全表扫描。 3、应...
  • 从索引、查询关键字、数据库表设计等多角度优化 SQL 。
  • 1.本文通过什么方法优化查询效率的? 2.如何增大RPC数量? 3.如何调整hbase内存? 环境:suse 8G内存,8核,12T磁盘  hbase master 占一台,其他7台作为hbase的region server 注意:此处不讨论hadoop 情景...
  • 代码性能优化建议

    千次阅读 2016-12-21 13:46:11
    这篇文章主要介绍一些小细节的优化技巧,虽然这些小技巧不能较大幅度的提升应用性能,但是恰当的运用这些小技巧并发生累积效应的时候,对于整个App的性能提升还是有不小作用的。通常来说,选择合适的算法与数据结构...
  • 建议系统设置一个流程,填写所以需求。就是一个需求说明 这个怎么 求大神解答。
  • C\C++代码优化的一些建议

    千次阅读 2016-02-28 20:33:00
    这并不意味着用8周时间一个全功能的射线追踪算法,然后用8周时间去优化它。 分多步来做性能优化。 先正确的代码,当你意识到这个函数可能会被经常调用,进行明显的优化。 然后再寻找算法的瓶颈
  • Android 性能优化之界面优化

    千次阅读 多人点赞 2019-06-27 18:12:14
    性能优化涉及到的方面很多,比如启动优化、卡顿优化、内存优化、界面布局优化、稳定性优化、耗电优化、安装包大小优化等等。性能优化是每个开发者都需要关注的功课,本文从界面布局优化做一个总结。
  • select查询语句的30条优化建议

    千次阅读 2018-08-14 09:22:55
    工作中往往要对十分庞大的数据库进行查询,如果语句的不到位,那速度可是会慢的吓人,甚至系统压根就没办法正常使用了,因此优化语句是每一个程序员必备的技能。以下是网上流传比较广泛的30种SQL查询语句优化方法...
  • 常用SQL语句的优化建议

    千次阅读 2020-03-25 16:57:04
    有关于优化SQL的建议 1. 查询SQL尽量不要使用select *,而是select具体字段。 反例子: SELECT * FROM employee; 正例子: SELECT id, NAME FROM employee; 理由: 只取需要的字段,节省资源、减少网络...
  • 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来从一个 10万条记录的表中查1条记录,那查询优化器会选择“索引查找”方式,如果...
  • oracle性能优化建议

    千次阅读 2017-12-07 16:38:36
    (1)连接查询的表顺序 在CBO模式下,当对多个表进行连接查询的时候,Oracle分析器会按照从右到左的顺序处理from字句中的...另一个建议是在要对单个字段值进行or计算的时候,可以考虑使用in来代替。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 387,001
精华内容 154,800
关键字:

优化建议怎么写