Nosql
一、NoSQL的基本说明
NoSQL(NoSQL = Not Only SQL),意味反sql运动,是一项全新的数据库革命性运动,早期就有人提出,发展至2009年趋势越发高涨。它指的是非关系型的数据库。
二、兴起的原因
随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的sns类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于本身的特点得到了非常迅速的发展。
三、特点
优点:
高并发读写的性能 大数据量的扩展(分布式存储) 配置简单
灵活、高效的操作与数据模型 低廉的成本
缺点:
没有统一的标准 没有正式的官方支持 各种产品还不算成熟
四、常见的nosql产品
新浪微博 Redis Google Bigtable Amazon SimpleDB 淘宝数据平台 Tair
优酷视频 MongoDB 飞信空间 HandlerSocket 视觉中国网站 MongoDB
Memcache
一、基本概念
-
Memcached是danga的一个项目,最早是LiveJournal 服务的,最初为了加速 LiveJournal 访问速度而开发的,后来被很多大型的网站采用。 官方网站: www.danga.com 和 memcached.org
-
Memcached是一个高性能的分布式的内存对象缓存系统,目前全世界不少人使用这个缓存项目来构建自己大负载的网站,来分担数据库的压力,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。简单的说就是将数据调用到内存中,然后从内存中读取,从而大大提高读取速度。(注: 摘自百度全科)
Memcached是一个高性能的分布式的内存对象缓存系统
分布式的概念:我们在实际的项目中可以使用多台memcache服务器,共同工作,存储的数据是分布式的。
二、memcache的安装
1、下载软件,并解压,拷贝到指定的位置,一般便于管理,和服务器的环境在同一个目录下
2、以管理员的方式进入到cmd窗口,并进入到memcache所在的目录
memcache.exe –d install 安装:安装完成后,通过Windows+R调出运行界面输入services.msc查看服务如下
3、安装完成后,启动memcache服务
memcached.exe –d start
启动后,可以通过netstat –an命令查看memcahce的端口是否监听状态,memcache的端口号是,11211
4、安装可能失败的原因:
a 如果你是用win7,win8系统,他对安全性要求高,因此,需要大家使用管理员的身份来安装和启动. 具体是 程序开始===>所有程序==》附件==》cmd(单击右键,选择以管理员的身份来执行)
b存放memcached.exe 目录不要有中文或者特殊字符
c 安装成功,但是启动会报告一个错误信息,提示缺少xx.dll ,你可以从别的机器拷贝该dll文件,然后放入到system32下即可.
d如果上面三个方法都不可以,可以直接 cmd>memcached.exe -p 端口 【这种方式不能关闭窗口】
5、在启动时指定的一些基本命令
-p 监听的端口 -l <ip地址>绑定地址(默认:所有都允许,无论内外网或者本机ip,有安全隐患,若设置为127.0.0.1就只能本机访问)
-d start 启动memcached服务 -d restart 重起memcached服务 -d stop|shutdown 关闭正在运行的memcached服务
-d install 安装memcached服务 -d uninstall 卸载memcached服务 -u 以的身份运行 (仅在以root运行的时候有效)
-m 最大内存使用,单位MB。默认64MB -M 内存耗尽时返回错误,而不是删除项 -c 最大同时连接数,默认是1024
-f 块大小增长因子,默认是1.25 -n 最小分配空间,key+value+flags默认是48 -h 显示帮助
三、如何连接memcache服务器进行使用
四、使用telnet连接到memcache服务器(类似于黑窗口)
连接方式:telnet ip地址 端口号 telnet localhost 11211
数据存储格式:类似于关联数组
第一列 第二列
键名(一般是字符串) 具体的数据内容(除了资源)
增删改查操作
1、添加数据
add 键的名称 0 缓存的时间 数据的长度 (回车后添加内容) 0表示不压缩:
比如:add color 0 100 3 表示向memcache里面添加的数据键为color,缓存的周期是100秒,数据的长度是3
2、获取数据
get 键名 get color
3、修改数据
replace 要求键名必须存在,如果不存在,则提示一个错误。
set set 指令也可以替换数据,如果键存在则替换,如果不存在,则等于添加。
4、删除数据
基本语法:delete 键名称
flush_all 清空所有的数据
5、其他的一些命令
6、获取memcache查询的成功率
memcache查询效率 = get_hits / cmd_get
五、通过php来连接memcache服务器
1、从网上下载memcache php的扩展,该扩展要和php的版本一致。要下载php版本对应的memcache的扩展。
2、把对应的memcache扩展拷贝到php安装目录的ext下面。
3、修改php配置文件php.ini打开扩展支持 extension=php_memcache.dll
4、重启apache,通过运行phpinfo()函数来进行测试。
5、简单使用,可以存储字符串、整数、小数、对象、数组,其中存储数组时只能是一维数组,存储时以序列化方式存储
<?php $mem=new Memcache(); $mem->connect("localhost",11211); //先完成数据的取出 //如果把取出的data数据给缓存到memcache里面 //取出的数据是由sql语句决定的。键由sql语句字符串,值就是取出的数据 $sql = "select title from dede_archives limit 5"; $key = md5($sql); echo $key; //先从memcache里面取出数据 $data = $mem->get($key);//根据键名称从memcache里面取出数据 //判断是否取出数据,如果数据为空,则从数据库里面获取数据。 if(!$data){ $conn = mysql_connect("localhost",'root','root'); mysql_query("use itdede"); //mysql_select_db(); mysql_query("set names utf8"); $res = mysql_query($sql,$conn); $data = array(); while($row=mysql_fetch_assoc($res)){ $data[]=$row; } //从数据库里面获取的数据,添加到memcache里面。 $mem->add($key,$data,MEMCACHE_COMPRESSED,100); } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN"> <head> <title>新建网页</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="description" content="" /> <meta name="keywords" content="" /> <script type="text/javascript"></script> <style type="text/css"></style> </head> <body> <?php foreach($data as $v){?> <li><?php echo $v['title']?></li> <?php }?> </body> </html>
六、通过使用memcahe客户端源码连接操作memcache服务器
使用范围:在没有php操作memcache扩展的前提下使用,推荐使用php,memcache的扩展。
测试前:要关闭扩展。具体的使用步骤:
1、把源码文件拷贝到项目的指定位置。
2、引入源码文件
七、把session文件存储到memcache
方法一:在php.ini文件中配置
1、设置存储方式: session.save_handler=memcache
2、设置存储位置:session.save_path="tcp://localhost:11211,tpc://192.168.1.89:11211"
session文件存储到memcache是通过sessionid作键的;把session文件存储到memcache后,不影响session的任何操作。
方法二:直接在文件中设置,其实这样更好,因为不会影响到别人的使用session的方式
ini_set("session.save_handler","memcache");
ini_set("session.save_path","tcp://localhost:11211");
八、memcache的分布式存储
原理如下图: 具体代码如下图:
如果只有一台电脑,无需虚拟机也可以模拟两台memcache 服务器。可以通过memcached.exe –p 11210来开启。
具体代码如图:
九、memcache的细节讨论
1、生命周期的问题
①秒数,但是有限制,不能超过 2592000秒(30天)。
②时间戳,比如我们要设置超过1个月,则如下设置
$mem->add('name1','yangguang',MEMCACHE_COMPRESSED,time()+3600*24*31);如果设置为0,则表示永不过期。
存储到memcache里面的数据,什么情况下会丢失:
(1)生命周期到了(2)关闭memcache服务(3)关机,重启。
2、memcache中善于存储哪些数据
①更新比较频繁的数据(用户的在线状态),查询比较频繁,数据量不是很大。
②安全性不是很高。
如果没有memcache这个产品,可以通过mysql的memory存储引擎。
3、memcache的安全性
①内网(两块网卡,memcache在启动时指定那台访问)
memcached –d –u root –l 192.168.1.100 –p 11211.指定只有192.168.1.100服务器才能访问。
②防火墙
在linux中,设置命令:iptables -a input -p 协议 -s 可以访问ip -dport 端口 -j ACCEPT
例如:
iptables –a input –p tcp –s 192.168.1.1 –dport 11211 –j ACCEPT
iptables –a input –p tcp –s 192.168.1.1 –dport 11211 –j ACCEPT
4、Memcached机制深入了解
①基于c/s架构,协议简单
②基于libevent的事件处理
③内置内存存储方式
④基于客户端的分布式
Redis
一、基本介绍
redis是一个开源的,先进的key-value存储。它通常被称为数据结构服务器,因为键可以包含字符串、哈希、链表、集合和有序集合。
(1)架构方式:c/s 客户端和服务器
(2)redis不仅可以存储到内存中,而且可以把数据同步到硬盘中,达到数据的存储持久化。
(3)redis数据存储是键值对,存储的值的类型有五种:string(字符串),hash(哈希),list(链表),set(无序集合),zset(有序集合),这些数据类型都支持push/pop、add/remove及取交集和并集及更丰富的操作、Redis支持各种不同方式的排序。
(4)提供的API语言包括:C C++ C# Clojure Common Lisp Erlang Haskell Java Javascript Lua Objective-C Perl PHP Python Ruby Scala Go Tcl
二、redis的安装
1、下载安装包
http://redis.googlecode.com/files/redis-2.4.17.tar.gz
2、编译程序
tar zxvf redis-2.4.17.tar.gz
cd redis-2.4.17
make
cd src && make install
3、为了便于管理,新建redis的管理目录
mkdir -p /usr/local/redis/bin
mkdir -p /usr/local/redis/etc
4、把配置文件移动到新建的etc目录下面(配置文件在redis解压目录中)
mv redis.conf /usr/local/redis/etc
5、把解压目录下面的src目录下面的一些文件移动到新建的bin目录下
mv mkreleasehdr.sh redis-benchmark redis-check-aof redis-check-dump redis-cli redis-server /usr/local/redis/bin
6、启动服务,通过bin目录下面的redis-server
启动格式:redis-server 指定的配置文件
/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf
7、启动后会占用当前的会话窗口,我们应该让他在后台启动,因此要修改配置文件
打开配置文件/etc/redis.conf,如果需要在后台运行,把daemonize项改为yes
8、关闭redis的服务重新启动
pkill redis-server
9、客户端连接
三、redis的数据类型
string(字符串):类似于memcache里面的数据存储方式 key values
hash(哈希):类似于关系型数据库里面的行,也是键值对,值里面又有键值对
list(链表):可以模拟队列和栈。数据存储是有顺序的。
队列:先进先出。栈:先进后出。
set(集合) 集合的示意图:
zset(有序集合) 集合里面的内容是有序的
四、redis的数据类型相关命令
1、string类型
String是最简单的类型,一个 key对应一个Value,String类型是二进制安全的。Redis的 string可以包含任何数据,比如jpg图片或者序列化的对象。
(1)set设置键值
语法:set 键名称 值。set name zhangsan,重新设置则直接覆盖
(2)get获取key对应的string值,如果key不存在返回nil
语法:get 键值。get name
(3)setnx设置键时,先判断否存在,如果已经存在则设置不成功,返回0,nx是not exist。
setnx name zhangsan
(4)setex设置key对应string类型的value,并指定键的有效期。
语法:setex 名称 有效期 值。setex color 10 red
(5)setrange替换字符串中字符。
语法:setrange 键名称 开始替换序号 替换的内容。setrange email 7 qq.com
(6)mset一次设置多个key的值,成功返回ok表示所有的值都设置了,失败返回0表示没有任何值被设置
语法: mset 名称1 值1 名称2 值2 mset name lisi age 18 height 168
(7)msetnx一次设置多个key,成功返回ok表示所有值都设置了,失败返回0表示没有任何值被设置,不覆盖已存在key
msetnx name lisi age 18 height 168
(8)getset设置key的值,并返回key的旧值。
getset name wangwu
(9)getrange获取key的value值的范围内的子字符串
getrange name 0 5
(10)mget一次获取多个key的值,如果对应key不存在则对应返回nil。
mget name age height
(11)incr对key值做加加操作并返回新值。incrby同incr类似,加指定值,key不存在会设置key,并认为原来value是0
incr age incrby age 45
(12)decr对key值做减减操作。decrby同decr类似,减指定值
decr age decrby age 45
(13)append给指定key的字符串追加value,返回新字符串值的长度
append name is man
(14)strlen取指定key的value值的长度
strlen name
2、hashes类型
Redis hash是一个string类型的field和value的映射表。它的添加、删除操作都是0(1)(平均)。hash特别适合用于存储对象。相较于将对象的每个字段存成单个string类型。将一个对象存储在hash类型中会占用更少的内存,并且可以更方便的存取整个对象。
(1)hset设置hash field为指定值,如果 key不存在,则先创建。
语法: hset 哈希名称 字段名称 值 hset myhash name xiaowang
(2)hget取出hash field的值。
语法:hget 哈希名称 字段名称 hget myhash name
(3)hsetnx设置hash field为指定值,如果key不存在,则先创建,如果存在则返回0。
hsetnx myhash name lisi
(4)hmset同时设置hash的多个field
语法:hmset 哈希名称 field1 value1 field2 value2 hmset hash2 name yuguo age 77
(5)hmget获取全部指定的hash field
语法:hmget 哈希名称 field1 field2 hmset hash2 name age
(6)hincrby指定的 hash field加上给定的值
hincrby hash2 age 20
(7)hexists测试指定的 field是否存在
hexists hash2 age
(8)hlen返回指定hash的field数量
hlen hash2
(9)hdel删除指定hash的field
语法:hdel 哈希名 field hdel hash2 age
(10)hkeys返回hash的所有field
hkeys hash2
(11)hvals返回hash的所有 value
hvals hash2
(12)hgetall获取某个hash中全部的field及value
hgetall hash2
3、lists类型及操作
list是一个链表结构,主要功能是push、pop、获取一个范围的所有值等等,操作中key 理解为链表的名字。redis的list类型其实就是一个每个子元素都是string 类型的双向链表。我们可以通过push、pop操作从链表的头部或者尾部添加删除元素,这样list既可以作为栈,又可以作为队列。
(1)lpush在key对应list的头部添加字符串元素。
语法:lpush 链表名称 值内容
(2)lrange获取链表里面的值
语法:lrange 链表名称 0 -1,注意0 和 -1 表示取值范围,从头部到尾部。
(3)rpush在key对应list的尾部添加字符串元素。
语法:rpush 链表名称 值内容
(4)linsert在key对应list的特定位置前或后添加字符串
(5)lset设置list中指定下标的元素值。注:下标从0开始计算
(6)lrem从key对应list中删除n个和value相同的元素。(n<0从尾删除,n=0全部删除)
(7)ltrim保留指定key的值范围内的数据
(8)lpop从list的头部删除元素,并返回删除元素
(9)rpop从 list的尾部删除元素,并返回删除元素
(10)rpoplpush从第一个list的尾部移除元素并添加到第二个list的头部
(11)lindex返回名称为key的list中 index位置的元素
(12)llen返回key对应list的长度
4、sets类型及操作
set是集合,它是string类型的无序集合。set是通过hash table实现的、添加、删除和查找的复杂度都是0(1)。对集合我们可以取并集、交集、差集。通过这些操作我们可以实现sns中的好友推荐和blog的tag功能。
(1)sadd向名称为key 的set中添加元素
语法:sadd 集合名 元素
(2)smembers 获取集合中内容,语法:smembers 集合名称
(3)srem删除名称为key的set中的元素
(4)spop随机返回并删除名称为key的set中一个元素
(5)sdiff返回所有给定key与第一个key的差集
(6)sdiffstore返回所有给定key与第一个key的差集,并将结果存为另一个key。
语法:sdiffstore 新的集合 集合1 集合2
(7)sinter返回所有给定key的交集
(8)sinterstore返回所有给定key的交集,并将结果存为另一个key
(9)sunion返回所有给定key的并集
(10)sunionstore返回所有给定key的并集
(11)smove从第一个key对应的set中移除member并添加到第二个对应的set中
(12)scard返回名称为key的set的元素个数
(13)sismember测试member是否是名称为 key的set的元素
(14)srandmember随机返回名称为key的set的一个元素,但不删除元素
5、sorted sets类型及操作
sorted set是set的一个升级版本,他在set的基础上增加了一个顺序属性,这一属性在添加修改元素的时候可以指定,每次指定后,zset会自动重新按新的值调整顺序。可以理解为有两列的mysql表,一列存value,一列存顺序。操作中的key理解为zset的名字。
(1)zadd向名称为key的zset中添加元素。如果该元素存在,则更新其顺序。
语法:zadd 集合名 序号 内容
(2)zrange获取有序集合中的内容
(3)zrem删除名称为key的zset中的元素member
(4)zincrby如果在名称为key的zset中已存在元素member,则该元素的score增加increment否则向该集合中添加该元素,其score的值为increment
(5)zrank返回名称为key的zset中member元素的排名(按score从小到大排序)即下标
(6)zrevrank返回名称为key的zset中member元素的排名(按score从大到小排序)即下标
(7)zrevrange返回名称为key的zset(按score从大到小顺序)中的index从start到end的所有元素
(8)zrangebyscore返回集合中score在给定区间的元素
(9)zcount返回集合中score在给定区间的数量
(10)zcard返回集合中元素的个数
(11)zremrangebyrank删除集合中排名在给定区间的元素
(12)zremrangebyscore删除集合中score在给定区间的元素
五、redis常用命令
redis提供了丰富的命令对数据库和各种数据库类型进行操作,这些命令可以在linux终端使用。
1、键值相关的命令
(1)keys返回满足给定参数的所有key。用表达式*,代表取出所有的key
(2)exists确认一个key是否存在
(3)expire设置一个key的过期时间
(4)move将当前数据库中的key转移到其它数据库中
(5)persist移除给定key的过期时间
(6)randomkey随机返回key空间的一个key
(7)rename重命名key
(8)type:返回值的类型
2、服务器相关命令
(1)select选择数据库。redis数据库编号从0-15,我们可以选择任一个进行数据的存取,若不在编号内会报错
(2)quit退出连接
(3)dbsize返回当前数据库中key的数目
(4)info获取服务器的信息和统计
(5)config get获取参数的配置。
本例中我们获取了dir这个参数配置的值,如果想获取全部参数的配置只需要执行”config get *”即可将全部的值都显示出来
(6)flushdb删除当前选择数据库中的所有key
(7)flushall删除所有数据库中的所有的 key
六、redis的安全性
设置客户端连接后进行任何其他操作前需要使用密码。注意:因为 redis速度相当快,所以在一台比较好的服务器下,一个外部的用户可以在一秒钟进行150k次的密码尝试,这意味着你需要指定非常非常强大的密码来防止暴力破解。
1、设置密码的方式,打开redis的配置文件
#requirepass 设置的密码 设置完密码后,redis服务要重启
比如:requirepass guangzhou
2、设置完成密码后,客户端登录方式
第一种方式:登录后,执行auth 设置的密码 后才能操作,否则不能任何操作
第二种方式:在登录时,输入密码 /usr/local/redis/bin/redis-cli –a 设置的密码
七、持久化机制
redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步到硬盘来保证持久化。
redis支持两种持久化方式:
1、snapshotting(快照)默认方式
快照是默认的持久化方式。这种方式是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。可以通过配置设置自动做快照持久化的方式。我们可以配置redis在n秒内如果超过m个key修改就自动做快照。
快照方式的缺点:由于快照方式是在一定间隔做一次的,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改。
2、append-only file( 缩写aof)的方式
aof比快照方式有更好的持久化性,是由于在使用aof时,redis会将每一个收到的写命令都通过write函数追加到文件中,当redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。
当然由于os会在内核中缓存write做的修改,所以可能不是立即写到磁盘上。这样aof方式的持久化也还是有可能会丢失部分修改。可以通过配置文件告诉reids我们想要通过fsync函数强制os写入到磁盘的时机。
八、redis配置文件常用的项
daemonize如果需要在后台运行,把该项改为yes pidfile:配置多个pid的地址 默认在/var/run/redis.pid
bind:绑定ip,设置后只接受来自该ip的请求 port:监听端口,默认为6379
timeout:设置客户端连接时的超时时间,单位为秒。 logfile:配置log文件的地址。
databases:设置数据库的个数,默认使用的数据库为0 sava:设置redis进行数据库镜像的频率。
rdbcompression:在进行镜像备份时,是否进行压缩。 Dbfilename:镜像备份文件的文件名。
Dir:数据库镜像备份的文件放置路径。 Slaveof:设置数据库为其他数据库的从数据库。
Masterauth:主数据库连接需要的密码验证。 Requirepass:设置登录时需要使用的密码。
Maxclients:限制同时连接的客户数量 Maxmemory:设置redis能够使用的最大内存。
Appendonly:开启append only模式。
九、php支持redis
1、下载扩展,在下载扩展时要注意,和php的版本要兼容
2、把对应的扩展拷贝到,php的安装目录ext目录下面
3、打开php.ini文件,引入扩展
4、重启apache进行测试,写一个文件,运行phpinfo()函数测试
5、基本使用