##生成N个不重复的随机数
转自Veda 原型

有25幅作品拿去投票,一次投票需要选16幅,单个作品一次投票只能选择一次。前面有个程序员捅了漏子,忘了把投票入库,有200个用户产生的投票序列为空。那么你会如何填补这个漏子?

当然向上级反映情况。但是我们这里讨论的是技术,就是需要生成1-25之间的16个不重复的随机数,去填补。具体怎么设计函数呢?将随机数存入数组,再在数组中去除重复的值,即可生成一定数量的不重复随机数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php
/*
* array unique_rand( int $min, int $max, int $num )
* 生成一定数量的不重复随机数
* $min 和 $max: 指定随机数的范围
* $num: 指定生成数量
*/
function unique_rand($min, $max, $num) {
$count = 0;
$return = array();
while ($count < $num) {
$return[] = mt_rand($min, $max);
$return = array_flip(array_flip($return));
$count = count($return);
}
shuffle($return);
return $return;
}
$arr = unique_rand(1, 25, 16);
sort($arr);
$result = '';
$result = '';
for($i=0; $i < count($arr);$i++)
{
$result .= $arr[$i].',';
}
$result = substr($result, 0, -1);
echo $result;
?>

补充几点说明:

  • 生成随机数时用了 mt_rand() 函数。这个函数生成随机数的平均速度要比 rand() 快四倍。
    去除数组中的重复值时用了“翻翻法”,就是用 array_flip() 把数组的 key 和 value 交换两次。这种做法比用 array_unique() 快得多。
  • 返回数组前,先使用 shuffle() 为数组赋予新的键名,保证键名是 0-n 连续的数字。如果不进行此步骤,可能在删除重复值时造成键名不连续,给遍历带来麻烦。

##一些优化
为了尊重作者,我还是不在原文里对内容进行修改了

  • for循环在使用时切记不要使用count(array)方式,php不像java会对这样的代码进行优化,这样的代码造成的结果是数组有多少个元素,就会执行多少次count(array)。
  • 把数组拼接成字符串可以使用implode函数
1
string implode ( string $glue , array $pieces )

Vulcan Logic Disassembler

本文翻译自http://rancoud.com/read-phps-opcode/
VLD(Vulcan Logic Disassembler)是一个向你解释zend引擎如何将你的脚本转化成opcode的扩展.
扩展下载地址
我将解释如何安装,使用并阅读opcode

首先,你要安装PEAR
aptitude install php-pear
然后就可以添加vld
pecl install "channel://pecl.php.net/vld-0.12.0"
编辑php.ini文件使扩展生效
注意,这个文件是cli模式的,跟php.ini不同
nano /etc/php5/cli/php.ini
将下面这行加到静态扩展区域
extension=vld.so

如何使用

1
php -dvld.dump_paths=1 -dvld.verbosity=0 -dvld.save_paths=1 -dvld.active=1 yourscript.php

以下列出参数列表及默认值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Activate extension: boolean
vld.active 0
# The caracter used for writing columns: carater
vld.col_sep "\t"
# Dumps branch and paths: boolean
vld.dump_paths 1
# Execute code in the same time: boolean
vld.execute 1
# Format output analyze: boolean
vld.format 0
# Where to save the file for graphviz .dot file: string
vld.save_dir /tmp
# dump path information has a graphviz .dot file: boolean
vld.save_paths 0
# suppresses output and loading of auto_append_file respectively if vld.active=1 and vld.execute=0: boolean
vld.skip_append 0
# suppresses output and loading of auto_prepend_file respectively if vld.active=1 and vld.execute=0: boolean
vld.skip_prepend 0
# Verbosities' level (0:none, 1, 2, 3): integer
vld.verbosity 1

现在我门可以看这个网站的结果
(http://blog.pascal-martin.fr/post/php-obtenir-dump-opcodes)
php代码

1
2
3
4
5
6
7
8
9
10
<?php
for ($i=0 ; $i>10 ; $i++) {
if ($i % 2 === 0) {
echo "Pair : ";
}
else {
echo "Impair : ";
}
echo $i, "\n";
}

VLD 输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
$ ~/bin/php-5.3/bin/php -dextension=vld.so -dvld.active=1 -dvld.verbosity=0 -dvld.execute=0 exemples/003-control.php
filename: /.../exemples/003-control.php
function name: (null)
number of ops: 16
compiled vars: !0 = $i
line # * op fetch ext return operands
---------------------------------------------------------------------------------
2 0 > ASSIGN !0, 0
1 > IS_SMALLER ~1 !0, 10
2 > JMPZNZ 6 ~1, ->15
3 > POST_INC ~2 !0
4 FREE ~2
5 > JMP ->1
3 6 > MOD ~3 !0, 2
7 IS_IDENTICAL ~4 ~3, 0
8 > JMPZ ~4, ->11
4 9 > ECHO 'Pair+%3A+'
5 10 > JMP ->12
7 11 > ECHO 'Impair+%3A+'
9 12 > ECHO !0
13 ECHO '%0A'
10 14 > JMP ->3
11 15 > > RETURN 1
branch: # 0; line: 2- 2; sop: 0; eop: 0; out1: 1
branch: # 1; line: 2- 2; sop: 1; eop: 2; out1: 15; out2: 6
branch: # 3; line: 2- 2; sop: 3; eop: 5; out1: 1
branch: # 6; line: 3- 3; sop: 6; eop: 8; out1: 9; out2: 11
branch: # 9; line: 4- 5; sop: 9; eop: 10; out1: 12
branch: # 11; line: 7- 9; sop: 11; eop: 11; out1: 12
branch: # 12; line: 9- 10; sop: 12; eop: 14; out1: 3
branch: # 15; line: 11- 11; sop: 15; eop: 15
path #1: 0, 1, 15,
path #2: 0, 1, 6, 9, 12, 3, 1, 15,
path #3: 0, 1, 6, 11, 12, 3, 1, 15,

如何阅读

在表格上面有两行

  • 操作执行的数量:有多少opcode操作将会被执行,这里是16
  • 编译的变量:php变量和它的opcode version,这里$i被表示成!0

其他方式

只翻译了部分,其他的不翻译了,因为我喜欢编译安装,所以vld也是编译安装
根据下载地址中的version,安装适合自己php的vld版本
可以使用php -v查看自己php的版本号
下载好后

1
2
3
4
5
6
$tar zxvf vld-0.12.0.tgz #解压
$cd vld-0.12.0/
$/usr/local/php/bin/phpize #根据自己的phpize实际位置使用
$./configure --with-php-config=/usr/local/php/bin/php-config --enable-vld
$sudo make
$sudo make install

这样就安装完成了,然后在php.ini中添加
extension=vld.so
一般编译安装的php.ini 放在php目录下的lib目录中
可以使用php -i |grep vld查看是否安装成功

下载

虽然Ubuntu提供了openjdk的使用,但是有时候apt-get的安装软件的配置信息并不熟悉,所以个人还是习惯自主安装
jdk7 的下载地址
必须accept才能下载


安装

我是在远程机器上安装的,所以还使用了scp等工具,这里就忽略了

1
2
3
4
$ sudo mkdir /usr/local/java
$ sudo tar zxvf jdk-7u21-linux-i586.tar.gz -C /usr/local/java
$ cd /usr/local/java
$ sudo mv jdk1.7.0_67 jdk

-C表示解压到指定文件夹,zxvf不说了
这样就在 /usr/local/java目录下生成了jdk目录


添加环境变量

1
$ sudo vi /etc/bash.bashrc

在最后一行添加如下代码

1
2
3
4
export JAVA_HOME=/usr/local/java/jdk
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH

使修改生效

1
$ source /etc/bash.bashrc


测试

最后 在终端中输入java -version

1
2
3
4
$ java -version
java version "1.7.0_67"
Java(TM) SE Runtime Environment (build 1.7.0_67-b01)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)

安装成功

code

按照权重随机,直接贴代码吧,思路大概就是在有限长线段上取一点,点落到某个区域内的概率有多大

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
/**
* @param array $weight 权重 例如array('a'=>10,'b'=>20,'c'=>50)
* @return string key 键名
*/
function roll($weight = array()) {
$roll = rand ( 1, array_sum ( $weight ) );
$_tmpW = 0;
$rollnum = 0;
foreach ( $weight as $k => $v ) {
$min = $_tmpW;
$_tmpW += $v;
$max = $_tmpW;
if ($roll > $min && $roll <= $max) {
$rollnum = $k;
break;
}
}
return $rollnum;
}
$row=roll(array('a'=>10,'b'=>20,'c'=>50));
echo $row;
?>

简介

awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理.


使用方法

基本语法如下,使用手册

1
awk '{pattern + action}' {filenames}

尽管操作可能会很复杂,但语法总是这样,其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。 pattern就是要表示的正则表达式,用斜杠括起来。


工作流程

awk工作流程是这样的:读入有’\n’换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域。默认域分隔符是”空白键” 或 “[tab]键”。如果想使用其他分隔符,可以使用-F指定域分隔符为’:’。


awk内置变量

1
2
3
4
5
6
7
8
9
10
11
ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk浏览的文件名
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令行 -F选项
NF 浏览记录的域的个数
NR 已读的记录数
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符

实例

  • 显示最近登录的5个帐号
1
2
3
4
$last -n 5 |awk '{print $1}'
root pts/0 101.229.11.88 Mon Dec 1 22:47 still logged in
wtmp begins Mon Dec 1 22:47:35 2014
  • 显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以tab键分割
1
2
3
4
5
6
$cat /etc/passwd |awk -F ':' '{print $1"\t"$7}'
root /bin/bash
daemon /usr/sbin/nologin
bin /usr/sbin/nologin
sys /usr/sbin/nologin
....
  • 搜索/etc/passwd有root关键字的所有行
1
2
$awk '/root/' /etc/passwd
$sed -n '/root/p' /etc/passwd #sed方式

买个kindle,下了点书,上下班路上就可以看书了.来到ajk后,版本控制一直使用的是git

Pro Git

image
强烈推荐这本书,解释的很详尽透彻。附上亚马逊地址


Git 内部原理

直接跳到这里吧,git的使用实在不想多写了。
从根本上来讲 Git 是一套内容寻址 (content-addressable) 文件系统,在此之上提供了一个 VCS 用户界面。
image
每个目录都创建了 tree对象 (包括根目录), 每个文件都创建了一个对应的 blob对象 . 最后有一个 commit对象 来指向根tree对象(root of trees), 这样我们就可以追踪项目每一项提交内容.

  • blob

存储的并不是文件名而仅仅是文件内容。这种对象类型称为 blob 。(git会为每一个改动后的文件生成一个blob,也就是一些文章中所说的快照)

  • tree

tree对象可以存储文件名,同时也允许存储一组文件。Git 以一种类似 UNIX 文件系统但更简单的方式来存储内容。所有内容以 tree 或 blob
对象存储,其中 tree 对象对应于 UNIX 中的目录,blob 对象则大致对应于 inodes 或文件内容。一个单独的 tree 对象包含一条或多条
tree 记录,每一条记录含有一个指向 blob 或子 tree 对象的 SHA-1 指针,并附有该对象的权限模式 (mode)、类型和文件名信息

  • commit

commit对象格式很简单:指明了该时间点项目快照的顶层树对象、作者/提交者信息(从 Git 设理发店的 user.name 和user.email中获得)
以及当前时间戳、一个空行,以及提交注释信息。

这三类 Git 对象 ── blob,tree 以及 tree ── 都各自以文件的方式保存在.git/objects 目录下。
可以在 objects 目录下看到这些文件。这便是 Git 存储数据内容的方式──为每份内容生成一个文件,取得该内容与头信息的 SHA-1 校验和,创建以该校验和前2个字符为名称的子目录,并以 (校验和) 剩下 38 个字符为文件命名 (保存至子目录下)。

示例

下面来尝试解释一下git的运行吧

1
2
$ git init #初始化git
$ ls -al #可以看到当前目录下产生了一个.git目录

看一下.git的目录结构
git 的本地化配置(git config –local 产生的配置会写到.git/config
.git/objects 里面会存储SHA-1码的一些东西
.git/HEAD 存储的是当前工作中的分支指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ find .git/
.git/
.git/hooks
.git/hooks/post-update.sample
.git/hooks/pre-rebase.sample
.git/hooks/pre-applypatch.sample
.git/hooks/commit-msg.sample
.git/hooks/applypatch-msg.sample
.git/hooks/pre-push.sample
.git/hooks/pre-commit.sample
.git/hooks/prepare-commit-msg.sample
.git/hooks/update.sample
.git/config
.git/description
.git/objects
.git/objects/info
.git/objects/pack
.git/info
.git/info/exclude
.git/refs
.git/refs/heads
.git/refs/tags
.git/branches
.git/HEAD

创建README并写入hello world

1
$echo 'hello word' > README.md

添加到暂存区

1
2
3
4
5
$ git add README.md
$ git commit -m 'first commit'
[master (根提交) d2a03d1] first commit
1 file changed, 1 insertion(+)
create mode 100644 README.md

查看暂存区中的提交

1
2
3
4
5
6
$git log
commit d2a03d1cece536133c49d3ea8f6c503c778307f7
Author: ericwang <orange.king@qq.com>
Date: Sat Oct 11 18:31:36 2014 +0800
first commit

查看.git/objects

1
2
3
4
5
6
7
8
9
10
$ find .git/objects/
.git/objects/
.git/objects/73
.git/objects/73/928f2dd793cbc72fcc2b1ba7d0585bfa91886a
.git/objects/info
.git/objects/pack
.git/objects/7f
.git/objects/7f/d5222177e8ffadda6437dc9cfa0630a2777673
.git/objects/d2
.git/objects/d2/a03d1cece536133c49d3ea8f6c503c778307f7

生成了3个文件

  • .git/objects/d2/a03d1cece536133c49d3ea8f6c503c778307f7
  • .git/objects/7f/d5222177e8ffadda6437dc9cfa0630a2777673
  • .git/objects/73/928f2dd793cbc72fcc2b1ba7d0585bfa91886a

可以看到 commit d2a03d1cece536133c49d3ea8f6c503c778307f7 对应的是.git/objects/d2/a03d1cece536133c49d3ea8f6c503c778307f7文件
其SHA-1码被拆分成2部分,第一部分是SHA-1码的前两位作为目录名,第二部分是剩下的38位作为文件名

查看commit对象

1
2
3
4
5
6
$ git cat-file -p d2a03d1cece536133c49d3ea8f6c503c778307f7
tree 73928f2dd793cbc72fcc2b1ba7d0585bfa91886a
author ericwang <orange.king@qq.com> 1413023496 +0800
committer ericwang <orange.king@qq.com> 1413023496 +0800
first commit

tree对象的SHA-1码为 73928f2dd793cbc72fcc2b1ba7d0585bfa91886a
对应的是 .git/objects/73/928f2dd793cbc72fcc2b1ba7d0585bfa91886a
继续查看tree对象

1
2
$ git cat-file -p 73928f2dd793cbc72fcc2b1ba7d0585bfa91886a
100644 blob 7fd5222177e8ffadda6437dc9cfa0630a2777673 README.md

blob对象的SHA-1码为7fd5222177e8ffadda6437dc9cfa0630a2777673
对应的是.git/objects/7f/d5222177e8ffadda6437dc9cfa0630a2777673文件
查看blob对象

1
2
$ git cat-file -p 7fd5222177e8ffadda6437dc9cfa0630a2777673
hello word

其存储的是就是我们最初写入的文本内容
下面继续向README.md中写入内容

1
2
3
4
5
$ echo 2 >>README.md
$ git add .
$ git commit -m 'second commit'
[master 897276c] second commit
1 file changed, 1 insertion(+)

生成了新的commit 对象 897276c61b6e00005f66a6b16477e872835b5408
查看新的commit对象

1
2
3
4
5
6
7
$ git cat-file -p 897276c61b6e00005f66a6b16477e872835b5408
tree 6f44b87201208be6247b73708470d2b6266b7063
parent d2a03d1cece536133c49d3ea8f6c503c778307f7
author ericwang <orange.king@qq.com> 1413027193 +0800
committer ericwang <orange.king@qq.com> 1413027193 +0800
second commit

其父commit是我们第一次的commit,tree对象是6f44b87201208be6247b73708470d2b6266b7063,
查看tree对象

1
2
$ git cat-file -p 6f44b87201208be6247b73708470d2b6266b7063
100644 blob d0a2ec18682f4d54a2507c0d0275248dc2d8dad2 README.md

查看blob对象

1
2
3
$ git cat-file -p d0a2ec18682f4d54a2507c0d0275248dc2d8dad2
hello word
2

可以看到,git为改动后的README.md生成了新的blob,区别于第一次提交产生的blob
查看.git/objects/下也可以看到,git为改动后的该文件新生成了1个commit,1个tree,1个blob

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ find .git/objects/
.git/objects/
.git/objects/73
.git/objects/73/928f2dd793cbc72fcc2b1ba7d0585bfa91886a
.git/objects/6f
.git/objects/6f/44b87201208be6247b73708470d2b6266b7063
.git/objects/89
.git/objects/89/7276c61b6e00005f66a6b16477e872835b5408
.git/objects/info
.git/objects/pack
.git/objects/d0
.git/objects/d0/a2ec18682f4d54a2507c0d0275248dc2d8dad2
.git/objects/7f
.git/objects/7f/d5222177e8ffadda6437dc9cfa0630a2777673
.git/objects/d2
.git/objects/d2/a03d1cece536133c49d3ea8f6c503c778307f7

接着 新建文件并写入内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ echo 'new file content' >newfile
$ git add .
$ git commit -m 'third commit'
[master e1107b4] third commit
1 file changed, 1 insertion(+)
create mode 100644 newfile
$ git cat-file -p e1107b460be89af8d508ac972270237d2f1c530f
tree 4c4d45c5a7485c475fd8fd1b53d26fddcf18f0cd
parent 897276c61b6e00005f66a6b16477e872835b5408
author ericwang <orange.king@qq.com> 1413028137 +0800
committer ericwang <orange.king@qq.com> 1413028137 +0800
third commit
$ git cat-file -p 4c4d45c5a7485c475fd8fd1b53d26fddcf18f0cd
100644 blob d0a2ec18682f4d54a2507c0d0275248dc2d8dad2 README.md
100644 blob 8e66654a5477b1bf4765946147c49509a431f963 newfile

第三次提交中对应的tree对象有两个blob,我们没有对README.md进行修改,所以git并没有为它新生成一个blob,而是继续使用原有的blob
画个图比较直观一些,画风不怎么样,哈哈
image
实际上,项目中的git对象关系远比这复杂的多,很多tree对象有很多子tree,子tree中又包含很多blob,blob存储的是某次文件修改生成的快照

下载

下载地址
选择stable版本,下载的是.tar文件,执行

1
tar xvf nginx*.tar

编译

1
2
3
4
5
6
7
8
9
10
$./configure --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/ac\
cess.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/\
nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/subsys/nginx --with-http_ssl_modu\
le --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_gzip_static_\
module --with-http_stub_status_module --with-http_perl_module --with-mail --with-mail_ssl_module --add-module=/root/app/nginx-1.6.2/modules/ngx_ht\
tp_substitutions_filter_module --with-pcre
$make
$sudo make install

一些问题

1.pcre问题
./configure: error: the HTTP rewrite module requires the PCRE library.
需要安装pcre

2.安装第三方模块http_substitutions_filter_module
github地址,不需要编译,参数- –add-module=/root/app/nginx-1.6.2/modules/ngx_ht\
tp_substitutions_filter_module 路径指定好就可以了

3.lc_all设置问题
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LANGUAGE = “en_US:”,
LC_ALL = (unset),
LC_CTYPE = “zh_CN.UTF-8”,
LANG = “en_US.UTF-8”
are supported and installed on your system.

需要设置LC_ALL=C

1
2
3
$echo 'export LC_ALL=C' >>/etc/bash.bashrc
$source /etc/bash.bashrc

4.perl问题
/usr/bin/ld: cannot find -lperl

Linux下编译应用程序常常会出现如下错误:

/usr/bin/ld: cannot find -lxxx
意思是编译过程找不到对应库文件。其中,-lxxx表示链接库文件 libxxx.so。有时候,由于库文件是编译过程临时生成的,如果前面出错也会导致出现这种情况,下面针对的是由于本机系统环境缺失而引起的。

一般出现这种错误有以下几种原因:

  • 系统缺乏对应的库文件;

  • 版本不对应;

  • 库文件的链接错误;

  • 库文件路径设置问题;

对应第一第二种情况,可以通过下载安装lib来解决,ubuntu大多数可以直接通过apt-get来安装:

apt-get install libxxx-dev

所以执行

$apt-get install libperl-dev


安装pcre

http下载地址
下载完成后

1
2
3
4
5
$tar xvf pcre-8.36.tar
$cd pcre-8.36/
$./configure

安装完会打印pcre信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
pcre-8.36 configuration summary:
Install prefix .................. : /usr/local
C preprocessor .................. : gcc -E
C compiler ...................... : gcc
C++ preprocessor ................ : g++ -E
C++ compiler .................... : g++
Linker .......................... : /usr/bin/ld -m elf_x86_64
C preprocessor flags ............ :
C compiler flags ................ : -g -O2 -fvisibility=hidden
C++ compiler flags .............. : -O2 -fvisibility=hidden -fvisibility-inlines-hidden
Linker flags .................... :
Extra libraries ................. :
Build 8 bit pcre library ........ : yes
Build 16 bit pcre library ....... : no
Build 32 bit pcre library ....... : no
Build C++ library ............... : yes
Enable JIT compiling support .... : no
Enable UTF-8/16/32 support ...... : no
Unicode properties .............. : no
Newline char/sequence ........... : lf
\R matches only ANYCRLF ......... : no
EBCDIC coding ................... : no
EBCDIC code for NL .............. : n/a
Rebuild char tables ............. : no
Use stack recursion ............. : yes
POSIX mem threshold ............. : 10
Internal link size .............. : 2
Nested parentheses limit ........ : 250
Match limit ..................... : 10000000
Match limit recursion ........... : MATCH_LIMIT
Build shared libs ............... : yes
Build static libs ............... : yes
Use JIT in pcregrep ............. : no
Buffer size for pcregrep ........ : 20480
Link pcregrep with libz ......... : no
Link pcregrep with libbz2 ....... : no
Link pcretest with libedit ...... : no
Link pcretest with libreadline .. : no
Valgrind support ................ : no
Code coverage ................... : no

执行make操作

1
2
3
$make
$sudo make install

pcre安装完成

##事件
最近由于运维部门回收机器,没有通知就关闭了一个redis服务,redis中主要是同步的小区,导致搜索页猜词逻辑没有获得小区名称,继而导致分词服务请求量下降,产生报警,500页面数量升高也产生报警。

迁移

既然要回收了,就要对redis进行迁移,最开始打算在脚本同步时写2份redis(脚本是每天都跑的),然后更改读的配置,但是这样要在每一处写入的地方去再写一次,非常笨拙。于是回想到最近读的redis相关书籍,redis做主从同步,然后把代码中的配置切到从reids不就可以了。

相关命令

redis主从命令很简单

1
2
SLAVEOF IP port //主从
SLAVEOF NO ONE //停止主从

遇到的问题

在同步rdb过程中,产生了溢出,原因应该是没有使用缓存剔除,导致out of memory。还是马神比较在行,修改从数据库配置,使用lru替换规则,保证同步过程顺利进行,然后在配置中修改了reids的ip和端口,顺利进行了迁移

测试环境机器的密码实在是太复杂了(没有跳板机),每次登录都要去找密码,所以干脆弄个免密码登录吧
首先是本地机器,因为装有git,所以已经生成好rsa公钥私钥了
如果没有生成过,可以使用

1
ssh-keygen -t rsa

生成,连续回车就可以

1
cat ~/.ssh/id_rsa.pub

会有输出,这就是生成的公钥
接下来登录到目标机器
执行如下操作

1
sudo vi ~/.ssh/authorized_keys

将生成的公钥内容粘贴到最下面即可

或者

1
echo 公钥内容 >> ~/.ssh/authorized_keys

修改文件权限

1
chmod 600 .ssh/authorized_keys

接下来在本地上就可以ssh免密码登录了

mysqldump

测试环境数据寥寥无几,测试又不会批量生成数据,只能从备份数据库中拉出来一些小表的数据填充
命令行下具体用法如下:

mysqldump -u用戶名 -p密码 -d 数据库名 表名 > 脚本名

  • 导出整个数据库结构和数据

    1
    mysqldump -h localhost -uroot -p123456 database > dump.sql
  • 导出单个数据表结构和数据

    1
    mysqldump -h localhost -uroot -p123456 database table > dump.sql

问题来了,
Got error: 1044: Access denied for user ‘*‘ to database ‘**‘ when doing LOCK TABLES

应该是数据库user的锁表权限问题,在导表时会锁表。加上–skip-lock-tables 就可以了

1
mysqldump -h localhost -uroot -p123456 --skip-lock-tables database table > dump.sql

information_schema

在对表做操作时,最好看一下表的一些信息

1
select * from information_schema. tables where talbe_name = 'xxx';#真是醉了 这个sql竟然不让放到blog里,我把.tables中间加了个空格

关于information_schema,具体看这里