Redis数据存储解决方案

http://www.tuicool.com/articles/77nUZn

1、背景

1.1 Redis简介

官方网站: http://redis.io/ ,Redis是REmote DIctionary Server的缩写。

Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。它跟 memcached 类似,不过数据可以持久化,而且支持的数据类型很丰富。它在保持键值数据库简单快捷特点的同时,又吸收了部分关系数据库的优点。从而使它的位置处于关系数据库和键值数据库之间。Redis不仅能保存Strings类型的数据,还能保存Lists类型(有序)和Sets类型(无序)的数据,而且还能完成排序(SORT)等高级功能,在实现INCR,SETNX等功能的时候,保证了其操作的原子性,除此以外,还支持主从复制等功能。Redis可以被看成是一个数据结构服务器。

Redis的所有数据都是保存在内存中,然后不定期的通过异步方式保存到磁盘上(这称为“半持久化模式”);也可以把每一次数据变化都写入到一个append only file(aof)里面(这称为“全持久化模式”)。

1.2 瓶颈

当前卡布西游项目,数据存储采用MySQL,主游戏库共分为20个库,分布在5台机器上,每个库数据量约为10G,各机器均采用RAID5加速磁盘访问;当同时在线人数达到5W时,DB磁盘IO压力很大,导致游戏卡,在线人数再上不去了。而Redis数据读写都是直接操作内存,可有效解决这一瓶颈。

1.3 解决方案概述

将部分数据压缩导入到redis后,总数据量约15G(转换成redis数据类型数据量),一主一从模型,共两组。一台机器内存32G,开20个实例,共40个实例;预估每个实例最多存储2G数据(现在没这么多)。多实例方便做持久化。

主库不做AOF,也不做快照,只在每晚12点计划任务做一次快照并转移到异地。从库开启AOF并1秒落地。

主库每5分钟插入一个时间点(crontab实现),方便从库AOF记录时间点,用于定点还原。

2、安装配置

2.1 硬件配置

Dell R410  32G内存;两个CPU,每个CPU 4个核心;300G硬盘

2.2 安装

a)安装TCMalloc库

wget http://download.savannah.gnu.org/releases/libunwind/libunwind-0.99-alpha.tar.gz   tar zxf libunwind-0.99-alpha.tar.gz   cd libunwind-0.99-alpha/   CFLAGS=-fPIC ./configure   make CFLAGS=-fPIC   make CFLAGS=-fPIC install

b)安装google-perftools:

wget http://google-perftools.googlecode.com/files/google-perftools-1.8.2.tar.gztar zxf google-perftools-1.7.tar.gz   cd google-perftools-1.7/   ./configure   make   make install   echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf   /sbin/ldconfig

 

c)安装redis

wget http://redis.googlecode.com/files/redis-2.2.14.tar.gztar xzvf redis-2.2.14.tar.gz   cd redis-2.2.14   make USE_TCMALLOC=yes

 

//make之后会在 src目录下产生redis-server  redis-cli  redis-benchmark  redis-check-dump

将其拷贝到/usr/local/redis/bin目录下,将配置文件redis.conf拷贝到/usr/local/redis/etc目录

//统一建立目录,方便管理

mkdir -p /usr/local/redis/bin

mkdir -p /usr/local/redis/etc

mkdir -p /usr/local/redis/var

mkdir -p /data/redis-data

# mkdir -p /data/redis-data/redis60{01,02,03,04,05,06,07,08,09,10}

检查tcmalloc是否生效

# lsof -n | grep tcmalloc

出现以下信息说明生效

redis-ser 13768   root  mem       REG        8,5  1616491     788696 /usr/local/lib/libtcmalloc.so.0.1.0

//装完后,可能libtcmalloc没有注册,没有上面信息,在mysqld_safe文件里加一条:

export LD_PRELOAD=/usr/local/lib/libtcmalloc.so

//再重启mysql(线上操作谨慎!!!)(使用tmalloc,内存分配效率更高)

2.3 配置

//当前规划一共开40个实例,每台机器20个实例,下面以实例01为例:

//配置文件名: redis6001.conf ~ redis6040.conf

daemonize yespidfile /var/run/redis6001.pidport 6001   timeout 300   loglevel debug   logfile /usr/local/redis/var/debug6001.log   syslog-enabled yes   databases 16   rdbcompression yes   dbfilename redis6001.rdb   dir /data/redis-data/redis6001   slave-serve-stale-data yes   requirepass My#redis appendonly no   no-appendfsync-on-rewrite no   vm-enabled no   hash-max-zipmap-entries 512   hash-max-zipmap-value 64   list-max-ziplist-entries 512   list-max-ziplist-value 64   set-max-intset-entries 512   activerehashing yes

 

3、主从同步备份及相关脚本

3.1 主从同步目的目标

主从的主要目的:数据持久化,灾难恢复,冗余。主库不落地,减少消耗。

3.2 主从配置

从库安装配置同主库一致,主库无需任何改动(允许从库访问),从库需增加两个地方配置:slaveof + AOF

slaveof 192.168.3.180 6301

masterauth My#redis

appendonly yes

appendfilename appendonly01.aof

appendfsync everysec

 

//配置文件名: slave6001.conf ~ slave6040.conf

daemonize yespidfile /var/run/slave6001.pid   port 6001   timeout 300   loglevel debug   logfile /usr/local/redis/var/debug6001.log   syslog-enabled yes   databases 16   rdbcompression yes   dbfilename slave6001.rdb   dir /data/redis-data/slave6001   slaveof 192.168.0.139 6001   masterauth My#redis slave-serve-stale-data yes   requirepass My#redis appendonly yes   appendfilename slave6001.aof   appendfsync everysec   no-appendfsync-on-rewrite no   vm-enabled no   vm-swap-file /tmp/redis.swap   vm-max-memory 0   vm-page-size 32   vm-pages 134217728   vm-max-threads 4   hash-max-zipmap-entries 512   hash-max-zipmap-value 64   list-max-ziplist-entries 512   list-max-ziplist-value 64   set-max-intset-entries 512   activerehashing yes

3.3 备份

备份策略:主库每晚12点串行给每个实例做一次快照(bgsave);从库每晚12点串行对AOF文件打包备份(tar),打包备份后做一次AOF文件压缩(bgrewriteaof)。每天的数据起始点是前一天晚上rewriteaof后的数据。

主库每晚12点串行给每个实例做一次快照(bgsave)。主库备份脚本(redis_bgsave.sh)

#!/bin/bash

#date=`date +%y%m%d_%H%M%S`

REDISPASSWORD=My#redis

for PORT in `seq 6001 6020`

do

/usr/local/redis/bin/redis-cli -h 127.0.0.1 -p $PORT -a $REDISPASSWORD bgsave

sleep 10

done

date >> /usr/local/redis/var/bgsave.log

从库每晚12点串行拷贝每个实例的AOF到其他目录并对其打包,压缩包要有异地备份,之后再压缩AOF(bgrewriteaof)。

从库备份AOF并bgrewriteaof脚本(redis_backup.sh :对单个实例)

#!/bin/sh

## FD:File Dir

## RD:Runing Dir

## 第一个参数为redis实例名

if [ $# -ne 1 ]; then

echo “Usage:$0  redis_name”

exit

fi

CURDATE=`date +%Y%m%d`

CURHOUR=`date +%Y%m%d_%H`

CURTIME=`date +%Y%m%d_%H%M%S`

REDISPASSWORD=My#redis

REDISNAME=$1

PORT=`echo $REDISNAME | cut -c6-9`

LOGFILE=/data/logs/redisbak/redis_allbak_${CURDATE}.log

if [ "${REDISNAME}" = "" ]; then

echo “redis name Error!”

exit 1

else

if [ ! -d "/data/redis-data/${REDISNAME}" ]; then

echo “redis name Error!”

exit 1

fi

fi

DDIR=/data/backup/redis/$CURHOUR

mkdir -p ${DDIR}

RDIR=/data/redis-data/$REDISNAME

cd ${RDIR}

tar -zcf $DDIR/${REDISNAME}_${CURTIME}.tar.gz $REDISNAME.aof

if [ $? != 0 ]; then

echo “tar error $REDISNAME.aof” >> $LOGFILE

#exit 1

fi

sleep 5

/usr/local/redis/bin/redis-cli -h 127.0.0.1 -p $PORT -a $REDISPASSWORD bgrewriteaof

sleep 5

###  delete old backup data dir  ###

#/bin/rm -rf `date -d -7day +”%Y%m%d”`

find /data/backup/redis/ -mtime +7 | xargs rm -rf

echo “Backup $REDISNAME ok at $CURTIME !” >> $LOGFILE

从库对所有实例备份(/data/sh/redis_allbak.sh)

#!/bin/sh

CURDATE=`date +%Y%m%d`

LOGFILE=/data/logs/redisbak/redis_allbak_${CURDATE}.log

for PORT in `seq 6001 6020`

do

/data/sh/redis_backup.sh slave${PORT} && echo “slave${PORT} ok `date +%Y%m%d_%H%M%S`” >> $LOGFILE 2>&1 || echo “slave${PORT} backup error” >> $LOGFILE 2>&1

done

 

4、操作注意事项

1. 若主库挂了,不能直接开启主库程序。若直接开启主库程序将会冲掉从库的AOF文件,这样将导致只能恢复到前一天晚上12的备份。

2. 程序在跑时,不能重启网络(程序是通过网络接口的端口进行读写的)。网络中断将导致中断期间数据丢失。

3. 确定配置文件全部正确才启动(尤其不能有数据文件名相同),否则会冲掉原来的文件,可能造成无法恢复的损失。

 

5、灾难恢复

5.1 主库故障,快速恢复到最近状态

描述:主库挂了(redis程序挂了/机器宕机了),从库正常,恢复到主库挂掉的时间点:去从库手动做一次快照,拷贝快照到主库相应目录,启动,OK。

在从库做一次快照,转移快照文件到其他目录,将快照文件目录拷贝到主库相应目录,启动主库,OK!

( /data/sh/redis_bgsave_cp.sh )

#!/bin/bash

REDISPASSWORD=My#redis

for PORT in `seq 6001 6020`

do

/usr/local/redis/bin/redis-cli -h 127.0.0.1 -p $PORT -a $REDISPASSWORD bgsave

sleep 5

done

sleep 15

for PORT in `seq 6001 6020`

do

SDIR=/data/redis-data/slave${PORT}/

DDIR=/data/redis_recovery/redis-data/

mkdir -p $DDIR/redis${PORT}/

cd $SDIR

cp -rf slave${PORT}.rdb $DDIR/redis${PORT}/redis${PORT}.rdb

#sleep 1

done

在主库将原来数据目录重命名。

从从库拷贝快照文件到主库。

启动主库。

5.2 恢复到当天12点状态

注意备份数据(当前状态AOF+正常退出快照)!

停止redis。

解压AOF(/data/sh/redis_untar.sh)

#!/bin/bash

DAY=20111102

SDIR=/data/backup/redis/20111102_00/

cd $SDIR

for PORT in `seq 6001 6020`

do

tar -zxf slave${PORT}_$DAY_*.tar.gz

sleep 2

done

切割AOF(/data/sh/redis_sed.sh)

#!/bin/bash

DDIR=/data/redis_recovery/

TAG=”TAG111101_1200″

for PORT in `seq 6001 6020`

do

SDIR=/data/backup/redis/20111102_00/

SAOF=${SDIR}/slave${PORT}.aof

line=`sed -n “/$TAG/=” $SAOF`

num=$[$line + 3]

mkdir -p ${DDIR}/slave${PORT}/

sed “${num},\$d” $SAOF > ${DDIR}/slave${PORT}/slave${PORT}.aof

done

将原来数据目录重命名。

将切割出来的AOF目录重命名为配置文件的数据目录。(注释主从同步配置项)。

启动从库。

做快照,拷贝到主库,启动主库(同5.1)。

5.3 恢复到两天或几天前12点状态

从库每晚备份要备份AOF未bgrewriteaof之前的数据,可根据当天晚上12点备份,没有bfrewriteaof之前的AOF文件来进行恢复,方法同5.2。

 

6、监控

6.1 Nagios监控

# /usr/local/redis/bin/redis-cli -h 127.0.0.1 -p 6301 -a My#redis info

used_memory_human:1.49G

master_link_status:down                          up/down

db0:keys=2079581,expires=0

//监控进程数(每台机器redis实例数)

define service{

use                         local-service

host_name                   119.147.163.xxx

servicegroups                 procs

service_description             redis_20

check_command                   check_nrpe!check_procs\!20:20\!20:25\!redis-server

}

//监控主从同步状态(获取从库master_link_status与keys的值)

//status=down直接严重警告,keys相差10警告,keys相差100严重警告

define service{

use                       local-service

#        hostgroup_name           kabuxiyou

host_name               119.147.161.xxx

servicegroups                              redis

service_description             redis_239

check_command          check_nrpe!check_redis_slave\!192.168.0.139\!6379\!127.0.0.1\!6380

}

//监控实例内存使用大小,1.8G警告,2G严重警告

define service{

use                                 local-service

#        hostgroup_name         kabuxiyou

host_name               119.147.161.xxx

servicegroups                              redis

service_description                   redis_mem_22

check_command                        check_nrpe!check_redis_mem\!127.0.0.1\!6381

}

 

7、资料

7.1 参考资料

Redis入门手册(zh_v1.0).pdf

http://www.infoq.com/cn/articles/tq-why-choose-redis

// 为什么使用 Redis及其产品定位

http://www.infoq.com/cn/articles/tq-redis-memory-usage-optimization-storage

// Redis内存使用优化与存储

http://www.infoq.com/cn/articles/tq-redis-copy-build-scalable-cluster

// Redis复制与可扩展集群搭建

http://blog.prosight.me/index.php/2011/08/802

// Redis中7种集合类型应用场景

7.2 版本

最新稳定版:

wget http://redis.googlecode.com/files/redis-2.2.14.tar.gz    // 2011.10.1

wget http://redis.googlecode.com/files/redis-2.4.2.tar.gz    // 2011.11.15

wget http://redis.googlecode.com/files/redis-2.4.10.tar.gz    // 2012.04.16

 

8、卡布西游Redis分布

8.1 服务器分布

服务器分布:                                                        实例名:                                     端口:

… … …

8.2 mysql转redis规则

1.Key命名规则

Key采用字母+数字的形式 避免多个应用使用同一个key的时候互相覆盖,主项目中的key采用GJ#[UID] 例:GJ12345678

2.字段命名规则

主项目中的key内包含多个字段 代表多个应用 目前给每个应用预留的字段取值范围为100(实际使用中字段不应该超过10个左右不然使用哈希的意义不大了)。

当前的预留字段划分:

100~199为成就相关(当前使用150、151 对应MySQL的achieve_user表的history与current字段)

200~299为妖怪相关(当前使用200 对应MySQL的spirit_store表 实际应用时应该会再多2个字段 对应MySQL的spiritmaster与spirit表)

3.实例划分规则

预计将划分40个实例 玩家数据根据玩家的UID取模来分配到不同的实例中(是否再分库未确定)

4.其他使用Redis划分规则

目前庄园也有部分数据使用redis 不过数据是放在一个单独的redis实例中(119.147.164.24)

根据应用不同使用不同的库和key值 Key命名规则为[应用名]-[UID] 例: GrowTimes-12345678 / StolenList-12345678

 

9、相关测试数据

//测试数据跟存储的数据以及机器硬件配置等有关,具体环境可能不太一样,仅做参考。

9.1 启动关闭

启动:1.6G AOF文件,132M RDB,启动时间107s,产生debug.log 128M,使用内存1.71G。

2G数据,启动约2分钟,主从同步约2分钟(内网)。

关闭:shutdown时间很短,一般1~2s,shutdown之前必须做save,save时间跟数据量有关,一般几秒。

9.2 数据量大小

简单set(set a 1),3万条约1M AOF,300K RDB;12万条约4M AOF,1M RDB。

set一条记录,AOF会记录些什么:

redis> set yuwei wangjiancheng

*3

$3

set

$5

yuwei

$3

wangjiancheng

9.3 备份打包

纯文本AOF:

tar -zcf *.tar.gz *              1.9G / 20s / 16M /

tar -jcf *.tar.bz2 *             1.9G / 150s / 5.3M /

当前线上使用redis,数据导入是二进制流格式(AOF文件为数据文件,非文本文件),而且导入前已经过一次压缩,所以压缩比例很低。

9.4 其他测试

实例配置文件中的数据目录不存在,实例无法启动。

AOF边写边打包(tar),不会造成数据损坏,tar只是读文件。

Redis运行过程中删除数据目录,不能bgsave,不能写AOF,从库能同步;从建目录也不能bgsave,不能写AOF。

Bgsave是放后台去执行的,所以bgsave;shutdown连写在一起会出问题,bgsave还未执行完就已经shutdown了。改用save。

主库实例重启后,从库会重新”全同步”一次,保存数据与主库一致。

网络闪断不会造成主从数据丢失,网络恢复后可以续传。

A实例快照文件,放B实例数据目录启动(文件名改成B实例数据文件),OK!

执行rewriteaof/ bgrewriteaof后,reidis根据内存数据,重新建立AOF,AOF重新排列顺序。

 

10、客户端连接redis

10.1 PHP

安装phpredis:

phpredis软件包地址(试了N个版本 只有这1个能在我们的定制系统环境装上 蛋疼)

http://ftp.nluug.nl/pub/NetBSD/packages/distfiles/php-redis/nicolasff-phpredis-2.1.3-0-g43bc590.tar.gz

cd /dist/src

tar xzf ../dist/nicolasff-phpredis-2.1.3-0-g43bc590.tar.gz

cd nicolasff-phpredis-43bc590

/usr/local/php/bin/phpize

## 如果PHP是安装的RPM包,需要安装php-devel

./configure –with-php-config=/usr/local/php/bin/php-config

make && make install

配置php.ini

vi /usr/local/php/lib/php.ini 
加入: 
extension = “redis.so”

重启 fastcgi 生效 /root/fastcgi_restart 
# php -m    //查看是否有redis,检查是否安装成功。

Redis扩展测试

测试代码:

<?php$redis = new Redis();$redis->connect(’127.0.0.1′,6379);$redis->set(‘test’,'hello world!’);echo $redis->get(‘test’);

?>

 

返回 hello world !表示成功

## 密码

$redis->auth(‘My#redis’);

## Error:

configure: error: invalid value of canonical build

## ./configure

./configure –with-php-config=/usr/local/php/bin/php-config

10.2 C++

antirez-hiredis-3cc6a7f.tar.gz                   340 KB

这个是官方的库,里面有个例子

跑这个,带参数 ./hiredis-test

例子应该是test.c

 

转载于:https://www.cnblogs.com/fvsfvs123/p/4319240.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/492491.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

量子通信是不是伪科学?潘建伟这样回应

来源&#xff1a;科技日报“墨子号”发射快三年了&#xff0c;到底有什么新发现&#xff1f;量子通信和公众有什么关联&#xff0c;到底是不是伪科学&#xff1f;10日&#xff0c;在全国政协十三届二次会议举行的记者会上&#xff0c;全国政协委员、中国科学技术大学常务副校长…

AI如何设计,才能人类利益最大化?

来源&#xff1a;国机智能机器人曾为现代互联网早期协议和架构设计做出贡献的Vint Cerf&#xff0c;用一个寓言来解释为什么在人工智能等新兴技术出现后&#xff0c;勇敢的领导力至关重要。想象一下&#xff0c;你住在一个被群山环绕的山谷底部的小社区里。在远处的山顶上有一块…

每天收获

每天至少看一个demo代码&#xff0c;并且每天试着写出自己的demo。不能完全靠网上的代码蒙骗自己。 转载于:https://www.cnblogs.com/happywangjia/p/4319387.html

编译 | 5G时代的游戏世界:一年后的AR与VR将会发生的几个变化

来源&#xff1a;spectrum5G已不再是研发中的技术&#xff0c;它已经离我们非常的近&#xff0c;全球许多运营商都在都在部署这一新技术。那么我们可以从这个新一代无线系统中得到什么&#xff1f;不只是更好的智能手机服务。许多公司&#xff0c;比如德国电信&#xff0c;诺基…

《麻省理工科技评论》发布“21世纪迄今十大最糟科技”

来源&#xff1a;网络大数据必须承认&#xff0c;人类总会犯错&#xff0c;在科技的发展上也是一样。所以&#xff0c;当最新一期的《麻省理工科技评论》评出今天这份“ 2000-2019 年糟糕科技清单”时&#xff0c;你千万不要以为这是一件容易的事情。如果某项科技没有达到让人欣…

javascript Array对象

一&#xff0c;创建数组对象 JavaScript的数组支持了对任何数据类型的支持&#xff0c;并不会像java&#xff0c;C#那样指定了数组类型只能存储这种类型。 我们可以使用以下三种方法来创建JavaScript数组对象&#xff0c; 1&#xff0c;var arrnew Array(); 2 , var arrnew Arr…

67 亿美金搞个图,创建知识图谱的成本有多高你知道吗?

来源&#xff1a;算法与数学之美摘要&#xff1a;我们知道强大的深度模型需要很多计算力&#xff0c;那你知道创建一个知识图谱的成本到底是多少吗&#xff1f;德国 Mannheim 大学的研究者最近仔细估算了各种知识图谱每创建一条记录所需要的成本&#xff0c;他们表示对于大型知…

怎样修改MFC中应用程序标题的图标?

一、单文档中修改程序标题的图标 1. 切换到ResourceView视图&#xff0c;右键点击Icon&#xff0c;选择“import” ,导入图标(.ico)文件 2. 在CMainFrame中的OnCreate()函数中添加如下代码&#xff1a; //设置标题栏的图标 HICON m_hIcon AfxGetApp()->LoadIcon(IDI_ICON…

黄仁勋的“数据梦” 英伟达豪掷69亿美金虎口夺食

来源 &#xff1a; Bloomberg 编译&#xff1a;网易智能 晗冰3月12日消息&#xff0c;据国外媒体报道&#xff0c; 图形图像芯片制造商英伟达同意斥资69亿美元收购芯片制造商Mellanox&#xff0c;其欲通过此举大举进军不断增长的数据中心芯片市场。据悉&#xff0c;英伟达对Mel…

MFC制作简易音乐播放器

// MFC音乐播放器Dlg.cpp : implementation file // #include "stdafx.h" #include "MFC音乐播放器.h" #include "MFC音乐播放器Dlg.h" #include "Mmsystem.h" #include "Digitalv.h" #pragma comment(lib,"Winmm.lib&…

即使达到5级自动驾驶阶段,自动驾驶“卡车”也不可能完全“无人”

来源&#xff1a;IEEE编译&#xff1a;大数据文摘 李雷、周素云感谢Waymo和Uber等创业公司&#xff0c;让我们知道了无人驾驶汽车是怎么回事。这些汽车或卡车上配备了大量的传感器&#xff0c;并且依靠强大的计算能力使人们可以放心乘坐。愿景是美好的&#xff0c;但是却忽视了…

iOS 两种方法实现左右滑动出现侧边菜单栏 slide view

现在很多的APP中都有slide view&#xff0c;左右滑动出现侧边菜单栏的功能&#xff0c;Weico这个应用就有。网上有很多第三方的类库实现了这种效果&#xff0c;其实自己代码写的话也是很简单的&#xff0c;下面我将介绍两种方法实现slide view。---- 一种是用第三方类库IIViewD…

MFC中如何给对话框添加背景图片

定位到 void CXXXDlg::OnPaint()&#xff0c;在if()...else()中的else()下添加如下代码&#xff1a; else { //CDialog::OnPaint();//要禁止这个调用 CPaintDC dc(this); CRect rect; GetClientRect(&rect); CDC dcMem; dcMem.CreateCompatibleDC(&am…

孙正义万字访谈:AI是我现在唯一关注的事情,我是科技的绝对信徒

来源&#xff1a;腾讯科技科技变革丝毫没有减速&#xff0c;自动化就是科技的终极使命&#xff01;这是孙正义在最新采访中再次强调的理念。在接受CNBC超长采访中&#xff0c;软银创始人、千亿美元愿景基金掌舵者一再表示&#xff0c;AI能解决人类无法解决的问题&#xff0c;未…

Oracle 直方图理论

一.何为直方图 直方图是一种几何形图表&#xff0c;它是根据从生产过程中收集来的质量数据分布情况&#xff0c;画成以组距为底边、以频数为高度的一系列连接起来的直方型矩形图&#xff0c;如图所示 二.ORACLE 直方图 在Oracle中直方图是一种对数据分布情况进行描述的工具。它…

怎样把MySQL的编码方式改为utf8?

一、当我们安装好MySQL后&#xff0c;单击电脑开始&#xff0c;然后运行cmd&#xff0c;记得必须要用管理员的身份运行。然后输入net start mysql 前面操作如果忘记采用管理员身份运行的话&#xff0c;会出现系统访问错误。 二、修改MySQL的编码方式为utf8 1、找到默认MySQL的安…

strcpy_s与strcpy的比較

strcpy_s和strcpy()函数的功能差点儿是一样的。strcpy函数&#xff0c;就象gets函数一样&#xff0c;它没有方法来保证有效的缓冲区尺寸&#xff0c;所以它仅仅能假定缓冲足够大来容纳要拷贝的字符串。在程序执行时&#xff0c;这将导致不可预料的行为。用strcpy_s就能够避免这…

要更有钱、更烧钱,OpenAI 重组,加速融资之路

来源&#xff1a;AI 科技评论OpenAI 是一个非盈利性的 AI 组织&#xff0c;他们雇佣了许多一流的研究和开发人员&#xff0c;在机器学习理论和深度学习应用方面多有诸多成果&#xff0c;我们曾经报道过的许多强化学习连续控制成果、5v5 DOTA AI「OpenAI Five」、自动生成人类水…

MFC基于单文档制作吹彩色泡泡程序

1、代码如下&#xff1a; // 吹彩色泡泡Doc.h : interface of the CMyDoc class // /#if !defined(AFX_DOC_H__559CF0A7_41F7_48A5_A356_774764C0E60F__INCLUDED_) #define AFX_DOC_H__559CF0A7_41F7_48A5_A356_774764C0E60F__INCLUDED_#if _MSC_VER > 1000 #pragma once #e…

centos设置开机自启动

在CentOS系统下&#xff0c;主要有两种方法设置自己安装的程序开机启动。 1、把启动程序的命令添加到/etc/rc.d/rc.local文件中&#xff0c;比如下面的是设置开机启动httpd。 复制代码#!/bin/sh # # This script will be executed *after* all the other init scripts. # You c…