目录
-------------------------------------
Nosql数据库概述
NoSQ数据库的分类
几种常见Nosql功能及应用场景介绍
redis简介
redis应用场景
redis安装与启动
redis服务初始化
redis服务启动与关闭
redis命令行操作
redis的安全设置
redis命令禁用和修改
php程序操作redis服务
php配置session保存到redis
python程序操作redis服务
-------------------------------------
Nosql数据库概述
NoSQL,意思是“不仅仅是SQL”,泛指非关系型的数据库。随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。
NoSQ数据库的分类
1、Key-Value存储数据库
这类数据库主要会使用到一个哈希表,这个表中有一个特定的键和一个指针指向特定的数据。举例如:Tokyo Tyrant,Redis, memcached,memcachedb,Voldemort,Oracle BDB等。
优点:处理大量数据,快速处理大量读写请求,编程友好。
2、列存储数据库。
这类数据库又叫BigTable类型数据库,通常是用来应对分布式存储的海量数据。键仍然存在,但是它们的特点是指向了多个列。如:Cassandra,Hbase,Riak。
优点:处理大量数据,应对极高写负载,高可用,支持跨数据中心
3、文档型数据库
同键值存储相类似。该类型的数据模型是版本化的文档,半结构化的文档以特定的格式存储,比如JSON。文档型数据库比键值数据库的查询效率更高。如:CouchDB,MongoDb。
优点:数据模型自然,编程友好,快速开发,web友好。
4、图形数据库
图形结构的数据库使用灵活的图形模型,并且能够扩展到多个服务器上。NoSQ数据库没有标准的查询语言(SQL),因此进行数据库查询需要制定数据模型。如:Neo4J,FlockDB ,GraphDB,InfiniteGraph。
优点:可以解决复杂的图问题。
几种常见Nosql功能及应用场景介绍
1、Redis
所用语言:C/C++
特点:运行速度异常快
内存数据库,支持硬盘存储
主从复制
采用简单数据或以键值索引的哈希表,但也支持复杂操作
支持sets
支持列表
支持哈希表
支持有序sets
Redis支持事务
支持将数据设置成过期数据
发布订阅功能允许用户实现消息机制
最佳应用场景:适用于数据变化快且数据库大小可遇见(适合内存容量)的应用程序。
例如:实时数据搜集、数据分析、实时通讯。
2、MongoDB
所用语言:C++
保留了SQL一些友好特性(查询,索引)。
主从复制
内建分片机制
支持 javascript表达式查询
可在服务器端执行任意的 javascript函数
在数据存储时采用内存到文件映射
采用 GridFS存储大数据或元数据
最佳应用场景:适用于需要动态查询支持,需要使用索引功能,需要对大数据库有性能要求。
例如:Web应用
3、HBase
所用语言: Java
特点:支持数十亿行,上百万列
在BigTable之后建模
采用分布式架构Map/reduce
对实时查询进行优化
高性能Thrift网关
通过在server端扫描及过滤实现对查询操作预判
支持 XML, Protobuf, 和binary的HTTP
对配置改变和较小的升级都会重新回滚
不会出现单点故障
堪比MySQL的随机访问性能
最佳应用场景:适用于偏好BigTable,并且需要对大数据进行随机、实时访问的场合。
例如: Facebook消息数据库
4、Neo4j
所用语言: Java
基于关系的图形数据库
可独立使用或嵌入到 Java应用程序
图形的节点和边都可以带有元数据
很好的自带web管理功能
使用多种算法支持路径搜索
使用键值和关系进行索引
为读操作进行优化
支持事务
支持在线备份,高级监控及高可靠性
最佳应用场景:适用于图形一类数据。
例如:公共交通网络,地图,网络拓谱,社交网络,推荐系统等
redis简介
redis是一个开源的、使用C语言编写的、支持网络交互的、基于内存支持持久化的Key-Value数据库。redis官网地址,http://redis.io/。
redis应用场景
redis的应用场景有很多,比如显示最新的项目列表、删除与过滤、排行榜、计数、实时分析、队列、缓存等。
国内比较有名的大规模使用redis的场景例如:新浪微博,堪称史上最大的Redis集群。
redis安装与启动
#到官网下载最新稳定版,本文使用的redis版本是redis-3.0.2
[root@redis ~]# mkdir /home/ju/tools -p [root@redis ~]# cd /home/ju/tools/ [root@redistools]# wget http://110.96.192.8:82/1Q2W3E4R5T6Y7U8I9O0P1Z2X3C4V5B/download.redis.io/releases/redis-3.0.2.tar.gz [root@redistools]# tar xf redis-3.0.2.tar.gz [root@redistools]# cd redis-3.0.2 [[email protected]]# less README [[email protected]]# make [[email protected]]# mkdir /app/redis-3.0.2 �Cp [[email protected]]# make PREFIX=/app/redis-3.0.2 install [[email protected]]# cd /app/redis-3.0.2/ [[email protected]]# tree . . └── bin ├── redis-benchmark #redis性能测试工具,可以测试在本系统本配置下的读写性能 ├── redis-check-aof #对更新日志appendonly.aof检查,是否可用 ├── redis-check-dump #用于检查本地数据库的rdb文件 ├── redis-cli #redis命令行操作工具,也可以用telnet根据其纯文本协议来操作 ├── redis-sentinel -> redis-server └── redis-server #redis服务器的daemon启动程序 1directory, 6 files [[email protected]]# ln -s /app/redis-3.0.2/ /app/redis [[email protected]]# ll /app/ 总用量 4 lrwxrwxrwx.1 root root 17 7月 12 10:50 redis -> /app/redis-3.0.2/ drwxr-xr-x.3 root root 4096 7月 12 10:48 redis-3.0.2 [[email protected]]# cd /app/redis [[email protected]]#
redis服务初始化
[root@redis redis]# echo "PATH=$PATH:/app/redis/bin/" >> /etc/profile [root@redis redis]# tail -1 /etc/profile PATH=/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/app/redis/bin/ [root@redis redis]# . /etc/profile [root@redis redis]# which redis-server /app/redis/bin/redis-server [root@redis redis]# redis-server -h Usage: ./redis-server [/path/to/redis.conf][options] ./redis-server - (read config from stdin) ./redis-server -v or --version ./redis-server -h or --help ./redis-server --test-memory <megabytes> Examples: ./redis-server (run the server with default conf) ./redis-server /etc/redis/6379.conf ./redis-server --port 7777 ./redis-server --port 7777 --slaveof 127.0.0.1 8888 ./redis-server /etc/myredis.conf --loglevel verbose Sentinel mode: ./redis-server /etc/sentinel.conf �Csentinel [root@redis redis]# mkdir /app/redis/conf [root@redis redis]# cp /home/ju/tools/redis-3.0.2/redis.conf /app/redis/conf/
redis服务启动与关闭
[root@redis redis]# redis-server /app/redis/conf/redis.conf & #指定配置文件后台启动,端口默认是6379 [1] 13712 [root@redis redis]# 13712:M 12 Jul11:05:52.225 * Increased maximum number of open files to 10032 (it wasoriginally set to 1024). _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 3.0.2(00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in standalone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 | `-._ `._ / _.-' | PID: 13712 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 13712:M 12 Jul 11:05:52.229 # Serverstarted, Redis version 3.0.2 13712:M 12 Jul 11:05:52.229 # WARNINGovercommit_memory is set to 0! Background save may fail under low memorycondition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf andthen reboot or run the command 'sysctl vm.overcommit_memory=1' for this to takeeffect. 13712:M 12 Jul 11:05:52.229 # WARNING youhave Transparent Huge Pages (THP) support enabled in your kernel. This willcreate latency and memory usage issues with Redis. To fix this issue run thecommand 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root,and add it to your /etc/rc.local in order to retain the setting after a reboot.Redis must be restarted after THP is disabled. 13712:M 12 Jul 11:05:52.229 # WARNING: TheTCP backlog setting of 511 cannot be enforced because/proc/sys/net/core/somaxconn is set to the lower value of 128. 13712:M 12 Jul 11:05:52.229 * DB loadedfrom disk: 0.000 seconds 13712:M 12 Jul 11:05:52.229 * The server isnow ready to accept connections on port 6379 [root@redis redis]# [root@redis redis]# echo"vm.overcommit_memory = 1" >> /etc/sysctl.conf [root@redis redis]# sysctl -p net.ipv4.ip_forward = 0 net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.default.accept_source_route =0 kernel.sysrq = 0 kernel.core_uses_pid = 1 net.ipv4.tcp_syncookies = 1 net.bridge.bridge-nf-call-ip6tables = 0 net.bridge.bridge-nf-call-iptables = 0 net.bridge.bridge-nf-call-arptables = 0 kernel.msgmnb = 65536 kernel.msgmax = 65536 kernel.shmmax = 68719476736 kernel.shmall = 4294967296 vm.overcommit_memory = 1
overcommit_memory参数说明
设置内存分配策略(可选,根据服务器的实际情况进行设置)
/proc/sys/vm/overcommit_memory
可选值:0、1、2。
0,表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
1,表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
2,表示内核允许分配超过所有物理内存和交换空间总和的内存
注意:redis在dump数据的时候,会fork出一个子进程,理论上child进程所占用的内存和parent是一样的,比如parent占用的内存为8G,这个时候也要同样分配8G的内存给child,如果分配的内存不足,可以会造成redis服务器dump数据失败。所以这里比较优化的内存分配策略应该设置为1(表示内核允许分配所有的物理内存,而不管当前的内存状态如何)。
[root@redis redis]# redis-cli shutdown #关闭redis服务,还可以手动加一个save参数,把内存写到磁盘 13712:M 12 Jul 11:15:42.218 # Userrequested shutdown... 13712:M 12 Jul 11:15:42.218 * Saving thefinal RDB snapshot before exiting. 13712:M 12 Jul 11:15:42.228 * DB saved ondisk #默认就会把内存数据dump到磁盘 13712:M 12 Jul 11:15:42.228 # Redis is nowready to exit, bye bye... [1]+ Done redis-server /app/redis/conf/redis.conf [root@redis redis]# ls bin conf dump.rdb
redis命令行操作
[root@redis redis]# redis-cli 127.0.0.1:6379> set k1 v1 #设置一个键值对 OK 127.0.0.1:6379> get k1 #获取一个键的值 "v1" 127.0.0.1:6379> del k1 #删除一个键 (integer) 1 127.0.0.1:6379> get k1 (nil) 127.0.0.1:6379> EXISTS k1 #判断这个键是否存在,存在返回1,不存在返回0 (integer) 0 127.0.0.1:6379> set k2 v2 OK 127.0.0.1:6379> set k3 v3 OK 127.0.0.1:6379> KEYS * #查看本库所有的键,默认是库0 1) "k3" 2) "k2" 127.0.0.1:6379> select 1 #切换到库1,redis默认有16个库0~15 OK 127.0.0.1:6379[1]> KEYS * (empty list or set) 127.0.0.1:6379[1]> select 15 OK 127.0.0.1:6379[15]> select 16 (error) ERR invalid DB index 127.0.0.1:6379> select 0 OK 127.0.0.1:6379> KEYS * 1) "k3" 2) "k2" 127.0.0.1:6379>quit [root@redis redis]# redis-cli -h192.168.116.204 -p 6379 set k4 v4 OK [root@redis redis]# redis-cli -h192.168.116.204 -p 6379 get k4 "v4" [root@redis redis]# telnet 192.168.116.2046379 Trying 192.168.116.204... Connected to 192.168.116.204. Escape character is '^]'. set k5 v5 +OK get k5 $2 v5 ^] telnet> quit Connection closed. [root@redis redis]# echo "set k6v6" |nc 192.168.116.204 6379 127.0.0.1:6379> get k6 "v6" 127.0.0.1:6379> help #查看帮助 redis-cli 3.0.2 Type: "help @<group>" toget a list of commands in <group> "help <command>" for help on <command> "help <tab>" to get a list of possible help topics "quit" to exit 127.0.0.1:6379> help set #根据命令查看帮助 SETkey value [EX seconds] [PX milliseconds] [NX|XX] summary: Set the string value of a key since: 1.0.0 group: string 127.0.0.1:6379> help @string #根据类型查看帮助 APPEND key value summary: Append a value to a key since: 2.0.0 BITCOUNT key [start] [end] summary:Count set bits in a string since: 2.6.0 此处省略N字 SETRANGE key offset value summary: Overwrite part of a string at key starting at the specifiedoffset since: 2.2.0 STRLEN key summary: Get the length of the value stored in a key since: 2.2.0 127.0.0.1:6379>
redis的安全设置
[root@redis redis]# vim/app/redis/conf/redis.conf …… 387 # Warning: since Redis is pretty fastan outside user can try up to 388 # 150k passwords per second against agood box. This means that you should 389 # use a very strong password otherwiseit will be very easy to break. 390 # 391 # requirepass foobared 392 requirepass feige #在配置文件加上这一行,feige是密码 …… [root@redis redis]# redis-cli shutdown [root@redis redis]# redis-server/app/redis/conf/redis.conf & #重启服务 [root@redis redis]# redis-cli 127.0.0.1:6379> KEYS * (error) NOAUTH Authentication required. #此时就需要密码验证了 127.0.0.1:6379> auth feige OK 127.0.0.1:6379> KEYS * 1) "k5" 2) "k7" 3) "k6" 4) "k4" 5) "k3" 6) "k2" 127.0.0.1:6379> quit [root@redis redis]# redis-cli -a feige #或者使用此种方法验证密码也可以 127.0.0.1:6379> KEYS * 1) "k5" 2) "k7" 3) "k6" 4) "k4" 5) "k3" 6) "k2"
redis命令禁用和修改
[root@redis redis]# vim /app/redis/conf/redis.conf …… 402 # rename-command CONFIGb840fc02d524045429941cc15f59e41cb7be6c52 403 rename-command set "" 404 rename-command get "juget" 405 # It is also possible to completelykill a command by renaming it into 406 # an empty string: 407 # 408 # rename-command CONFIG "" …… [root@redis redis]# redis-cli -a feigeshutdown #由于上一节,所以这里关闭服务需要验证密码了 [root@redis redis]# redis-server/app/redis/conf/redis.conf & (error) ERR unknown command 'set' #这里就已经提示命令找不到了 127.0.0.1:6379> set k8 v8 (error) ERR unknown command 'set' 127.0.0.1:6379> get k7 (error) ERR unknown command 'get' 127.0.0.1:6379> juget k7 #重命名后的get为juget可以使用 "v7"
#这里仅作测试,还是改回原样吧,生产中可以把一些危险的操作命令改个名或者屏蔽,比如flushdb命令
php程序操作redis服务
[root@redis tools]# wget https://github.com/nicolasff/phpredis/archive/master.zip [root@redis tools]# unzip master.zip [root@redis tools]# cd phpredis-master/ [root@redis phpredis-master]#/app/php/bin/phpize [root@redis phpredis-master]# ./configure--with-php-config=/app/php/bin/php-config [root@redis phpredis-master]# make [root@redis phpredis-master]# make install [root@redis phpredis-master]# ll/app/php-5.6.11/lib/php/extensions/no-debug-non-zts-20131226/ 总用量 2540 -rwxr-xr-x. 1 root root 901139 7月 12 13:24 redis.so [root@redis php]# vim /app/php/lib/php.ini #增加以下两行 extension_dir = "/app/php-5.6.11/lib/php/extensions/no-debug-non-zts-20131226/" extension = redis.so [root@redis web]# cat redis.php <?php $redis = new Redis(); $redis->connect('192.168.116.204',6379); $redis->auth('feige'); $redis->set('k10', 'v10'); $var = $redis->get('k10'); echo "$var\n"; ?> [root@redis web]# /app/php/bin/phpredis.php v10
#用页面显示的这里就不演示了,没有CGI环境,有兴趣的自己搭个环境测试吧
php配置session保存到redis
phpredis还支持作为Session的Handler,配置如下:
session.save_handler = redis session.save_path = "tcp://192.168.116.204:6379?weight=1,timeout=2.5
python程序操作redis服务
[root@redis tools]# wget https://pypi.python.org/packages/source/r/redis/redis-2.10.1.tar.gz [root@redis tools]# tar xfredis-2.10.1.tar.gz [root@redis tools]# cd redis-2.10.1 [root@redis redis-2.10.1]# python setup.pyinstall [root@redis redis-2.10.1]# python Python 2.6.6 (r266:84292, Jan 22 2014,09:42:36) [GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] onlinux2 Type "help","copyright", "credits" or "license" for moreinformation. >>> import redis >>> r =redis.Redis(host='192.168.116.204',port=6379,password='feige',db=0) >>> r.set('k9','v9') True >>> r.get('k9') 'v9' >>> r.keys() ['k4', 'k2', 'k7', 'k3', 'k6', 'k9', 'k5']
今天就写到这,后续还有关于redis的主从同步、多实例,持久化等一系列博文~