Nosql 数据库分类
1、键值存储数据库
Redis。
典型应用:内容缓存,主要用于处理大量数据的高访问负载。
优势:快速查询
劣势:存储的数据缺少结构化
2、列存储数据库
HBase
典型应用:分布式的文件系统
3、文档型数据库
MongoDB
典型应用:Web应用(与Key-Value相似,Value是结构化的)
优势:数据结构要求不严格
劣势:查询性能不高,缺乏统一的查询语法
4、图形数据库
典型应用:社交网络
数据模型:图结构
Redis简介
Redis
C语言开发的一个开源的 高性能键值对数据库。
应用场景
缓存(数据查询、短链接、新闻内容、商品内容等等)使用最多
分布式集群架构中的 session 分离。
聊天室的在线好友列表
任务队列(秒杀、抢购)
应用排行榜
网站统计访问
数据过期处理(可以精确到毫秒)
。。。
安装 redis 及启动关闭
wget xxxx
tar zxf xxx.xx
rpm -qa | grep gcc
yum install gcc-c++
make
make install PREFIX=/usr/local/reids
redis服务打开和关闭
推荐使用打开方式
./redis-server redis.conf #redis.conf 需要配置 `daemonize yes`
推荐关闭方式
./redis-cli shutdown #不推荐非正常关闭 `kill 5528`
redis服务连接 【客户端】
- 使用自带的可执行文件
redis-cli
./redis-cli [ -h 127.0.0.1 -p 6379 ]
127.0.0.1:7379>exit
- 图形界面客户端
- 需要关闭防火墙或修改相关其配置
vi /etc/sysconfig/iptables
service iptables restart
redis 默认是 16个数据库,每个数据库之间是相互隔离的。数据库的数量在 redis.conf 中配置的
切换数据库
select 数据库编号。
使用 java 操作 redis
依赖
jedis-3.3.0.jar
commons-pool2-2.8.0.jar
@Test
public void test1(){
Jedis j = new Jedis("127.0.0.1", 6379);
//System.out.println(j);
Map<String, String> person = j.hgetAll("person");
System.out.println(person);
j.close();
}
使用连接池连接
@Test
public void test2(){
//创建连接池。需要依赖 slf4j-api-xxx.jar
JedisPool pool = new JedisPool("127.0.0.1", 6379);
Jedis j = pool.getResource();
Map<String, String> person = j.hgetAll("person");
System.out.println(person);
j.close();
pool.close();
}
spring 整合 jedispool
- 自学。配置bean
数据类型
- 字符串
- Hash类型
- List
- Set
- SortedSet(zset)
string
select n 使用 第n号数据库
set key value
mset k1 v1 k2 v2 .... 批量存入
mget k1 k2 .... 批量取值
getset key value 先取后存
del key 删除键值
incr num num自增,如果num不存在则相当于 set num 1
incrby num 2 指定递增数量
decr key key递减
decrby key 2 指定递减数量
set str hello
append str world 向str末尾追加内容,如果不存在str则指定str伪world
strlen s 获取字符串长度
自增
- 商品编号、订单号采用 string 的递增数字特性生成
incr items:id
hash
- 散列类型
hset 插入时返回 1,更新时返回 0
hset key field value 一次设置一个字段
hmset key f1 v1 f2 v2 .... 一次设置多个字段
hsetnx user age 30 如果 user.age不存在则设置age=30,存在则不做
hget user username 获取值
hmget user username age 获取多个值
hgetall user 获取所有字段值。返回字段和值
hdel user username age ... 删除一个或多个字段
hincrby user age 2 增加数字
hexits user age 判断user.age是否存在
hkeys user 只获取字段名
hvals user 只获取字段值
hlen user 获取字段总数
应用:存储商品信息
127.0.0.1:6379>hmset items:1001 name ipad-pro-9.7 price 3999 color black stock 300
OK
hgetall items:1001
hget items:1001 price
hmget items:1001 price stock
list
- 内部使用 双向链表实现
lpush key v1 v2 ... 依次往左边放 多个元素
rpush key v1 v2 .. 依次往右边放 多个元素
lrange key start stop 查看链表key的范围[start, stop],start从0开始
- 读所有:lrange key 0 -1
lpop key 从左边弹出一个元素
rpop key 从右边弹出一个元素
llen key 查看列表长度
lrem key count value
- count=0,删除所有值为value的元素
- count>0,会从列表左边开始,删除count个值
- count<0,会从列表右边开始,删除count个值
lindex key index 获取index位置的元素
lset key index value 更新index位置的值为value
ltrim key start end 只保留[start, end]范围内的值
linsert key before/after pivot value 在列表中从左到右查找值为 pivot 的元素,在其前或者后插入value
rpoplpush src dest 将src最右边的元素转移到 dest最左边
应用:商品评论列表
lpush items:comment:1001 '{"comment":"good!", "date":"1212125121"}'
lpush items:comment:1001 '{"comment":"goodxxxx!", "date":"121474572125121"}'
lpush items:comment:1002 '{"comment":"badxx!", "date":"123463125121"}'
set
- 不能重复,没有顺序
sadd key a b c ... 添加多个元素
srem key a b c ... 删除多个元素
smembers key 查看集合中的元素
集合运算
- 差集A-B
sdiff key1 key2 属于A并且不属于B的元素
- 交集A∩B
sinter key1 key2 同时属于A和B的元素
- 并集A∪B
sunion key1 key2 属于A或者属于B的元素
scard key1 集合中元素个数
spop key 从集合中随机弹出一个元素
sortedSet
- 不可重复,有序的集合
zadd sset:rank 100 engure 98 jack 80 lily ... 向有序集合添加多个元素
- zadd sset:1 score1 member1 score2 member2 .... score1 score2 等等默认从小到大排列
zscore sset:rank engure 获取元素的值,engure的分数
- 根据 key 获取 value
zrem sset:rank engure 删除值
- 根据 key 删除键值
zrange sset:rank 0 2 返回分数从小到大、在[0,2]范围内的key
-
根据 value 的区间返回其中的所有 key
-
如果希望 value 从大到小,则使用 zrevrange sset:rank 0 2
-
如果希望同时返回键值,需要加上参数 withscores
- zrerange sset:rank 0 2 withscores
获取指定分数范围内的元素
zrangebyscore sset:rank 90 97 withscores
zrangebyscore sset:rank 70 97 limit 1 2 添加分页功能
zincrby sset:rank 4 engure 给engure加4分
zcard sset:rank 查看元素总个数
zcount sset:rank 80 90 统计[80,90]区间满足条件的个数
zremrangebyrank key start stop 按照排名范围删除元素
-
zremrangebyrank rank 0 1 删除前两名(默认升序)
-
zremrangebyrank rank 0 -1 删除所有元素
zremrangebyscore key min max 按照分数范围删除元素
zrank key memeber 获取member从小到大的排名
zrevrank key member 获取member从大到小的排名
应用:商品销售排行榜
初始化排行榜 zadd items:sset 0 1001 0 1002 ....
更新销量 zincrby items:sset 1 1001 1001号商品销量加一
查看销量前十名 zrevrange items:sset 0 9 withscores
keys
keys [pattern]
keys *
keys zhang* ; *指代多个字符
keys a?c;?指代一个字符
exists xxx
rename keyname newkeyname
expire keyname time 设置超时时间
- 超时后就被删除了
ttl keyname 查看剩余的超时时间
- -1 表示没有设置超时时间
- -2 表示以 超时或不存在
type keyname 查看类型
- string、list、hash、zset、set
del keyname 删除一个key
redis 持久化方案
RDB持久化
- 默认持久化方案
- 通过快照 snapshotting 完成,当符合条件时redis将内存中的数据进行快照并持久化到硬盘
# Save the DB on disk:
#
# save <seconds> <changes>
#
# Will save the DB if both the given number of seconds and the given
# number of write operations against the DB occurred.
#
# In the example below the behaviour will be to save:
# after 900 sec (15 min) if at least 1 key changed
# after 300 sec (5 min) if at least 10 keys changed
# after 60 sec if at least 10000 keys changed
#
# Note: you can disable saving completely by commenting out all "save" lines.
#
# It is also possible to remove all the previously configured save
# points by adding a save directive with a single empty string argument
# like in the following example:
#
# save ""
save 900 1
save 300 10
save 60 10000
# The filename where to dump the DB
# 指定持久化文件名
dbfilename dump.rdb
# The working directory.
#
# The DB will be written inside this directory, with the filename specified
# above using the 'dbfilename' configuration directive.
#
# The Append Only File will also be created inside this directory.
#
# Note that you must specify a directory here, not a file name.
# 指定目录
dir ./
AOF持久化方案
- 没操作一次就进行一次持久化
- 默认关闭
# AOF and RDB persistence can be enabled at the same time without problems.
# If the AOF is enabled on startup Redis will load the AOF, that is the file
# with the better durability guarantees.
#
# Please check http://redis.io/topics/persistence for more information.
# 开启AOF持久化方案
appendonly yes
# The name of the append only file (default: "appendonly.aof")
# 默认文件名,后缀是 .aof
appendfilename "appendonly.aof"
redis 的主从复制
持久化保证了即使redis服务重启也不会丢失数据,因为redis会将硬盘上持久化的数据恢复到内存中;
考虑redis服务器可能会导致数据丢失。硬盘损坏等等
如果通过 redis的主从复制机制 就可以避免这种单点事故。
- 主 redis中的数据 自动被备份到 从redis中
- 多级主从redis图。a相对于b来说是主/从redis。
# Master-Slave replication. Use slaveof to make a Redis instance a copy of
# another Redis server. A few things to understand ASAP about Redis replication.
#
# 1) Redis replication is asynchronous, but you can configure a master to
# stop accepting writes if it appears to be not connected with at least
# a given number of slaves.
# 2) Redis slaves are able to perform a partial resynchronization with the
# master if the replication link is lost for a relatively small amount of
# time. You may want to configure the replication backlog size (see the next
# sections of this file) with a sensible value depending on your needs.
# 3) Replication is automatic and does not need user intervention. After a
# network partition slaves automatically try to reconnect to masters
# and resynchronize with them.
#
# slaveof <masterip> <masterport>
slaveof 192.168.129.217 6380
配置 redis 服务的端口号
# Accept connections on the specified port, default is 6379 (IANA #815344).
# If port 0 is specified Redis will not listen on a TCP socket.
port 6379
使用 slave redis
./redis-cli -h xxx -p xxx
# 错误!从redis是 read-only,不可写入
set a b
使用 master redis
./redis-cli -h xxx -p xxx
# 可读可写
redis 集群
tomcat 集群,使用 nginx 负载均衡
redis-cluster 集群架构图
安装 ruby
yum install ruby
yum install rubygems
集群管理工具 redis-3.0.0.gem
配置
# 安装 ruby 和 redis 的接口程序
gem install /usr/local/redis-3.0.0.gem
# 创建集群目录
mkdir redis-cluster # /usr/local/redis/ 下
# 复制文件 redis-trib.rb (配置集群的文件) 到 redis-cluster/ 下
cp /redis-3.0.0/src/redis-trib.rb /usr/local/redis/redis-cluster
搭建集群
# redis-cluster/ 下创建多个目录代表多个 redis服务器,比如 7001, 7002,7003,
# 复制 /bin 到各redis服务器目录
# 修改每个redis服务器的配置文件
cluster-enable yes
port 7001
######################
# 编写两个shell脚本,分别用来 打开集群、关闭集群
# 使用 redis-trib.rb 管理集群 (将 打开的redis服务器 关联起来)
./redis-trib.rb create --replicas 1 192.168.217.129:7001 192.168.217.129:7002 192.168.217.129:7003
# 自动指定主从redis
# 删除节点
./redis-trib.rb del-node ip:port 节点id
连接集群和使用redis
# -c 以集群的方式连接
./redis-cli -h 127.0.0.1 -p 7001 -c
# 连接一个节点,set/get时可能会使用另外一个节点
集群命令
# 以集群方式连接redis
cluster info
cluster nodes
jedis 连接集群
- 简单使用
- spring 使用 redis集群
创建 bean:JedisCluster