一.NoSQL概述
1.NoSQL是什么?
not only sql,意为不仅仅是sql,泛指非关系型数据库。用于超大规模数据的存储
2.Nosql数据库四大分类?
kv键值:MemcacheDB,Redis
文档型数据库:MongoDB
列存储数据库:HBase
图关系数据库:Neo4J
3.cap定理?
对于一个分布式计算系统来说,不可能同时满足以下三点,而由于当前网络硬件肯定会出现延迟丢包等问题,所以分隔容忍是必须满足的:
- 一致性(Consistency) (所有节点在同一时间具有相同的数据)
- 可用性(Availability) (保证每个请求不管成功或者失败都有响应)
- 分隔容忍(Partition tolerance) (系统中任意信息的丢失或失败不会影响系统的继续运作)
CA:传统的Oracle数据库
AP:大多数网站架构的选择
CP:redis,Mongodb
4.base理论?
BASE就是用来解决数据库强一致性引起的可用性降低而提出的解决方案
思想就是让系统放松对某一时刻数据一致性的要求来换取系统整体伸缩性和性能的改观
BASE是下面三个术语的缩写:
基本可用:(Basically Avialible)
软状态:(soft state)
最终一致:(Eventually consistent)
5.分布式+集群?
分布式:不同的服务器上部署不同的服务模块
集群:不同的服务器上部署相同的服务模块
二.redis
1.redis是什么?
remote Dictionary server(远程字典服务器),是高性能的key-value分布式基于内存的,并支持持久化的NoSql数据库
2.redis的特点?
3.redis的安装
1.下载:wget http://download.redis.io/releases/redis-4.0.8.tar.gz
2.解压:tar -zxvf redis-4.0.8.tar.gz
3.安装
cd redis-4.0.8
make
4.redis知识讲解
5.redis五大数据类型
6.redis数据结构
(1)String
set company zhada //创建
get company //根据key获取value
getset company baidu //获取value并设置
del person //删除
incr num //数字自增1
incrby num 5 //数字加5
append num 5 //追加5 eg:num为5 append 5后为55
(2)hash
hset myhash username kaka //添加键值对
hget myhash username //根据建查值
hgetall myhash //获取所有键值对
hkeys myhash //获取所有键
hvalues myhash //获取所有值
hdel myhash usrname age //删除指定键值对
del myhash //删除所有键值对
hlen myhash //获取键值对个数
(3)list
lpush mylist a b c //从集合左侧开始插入数据
rpush mylist abc //从右侧开始添加
lrange mylist 0 -1 //c b a 查看
lpop mylist //弹出第一个元素
rpop mylist //尾部弹出
llen mylist //元素个数
lset mylist 3 kaka //设置第三个位置的元素为kaka
linsert mylist before kaka mu //在kaka元素前添加mu
(4)set(不可重复)
sadd myset a b c //添加元素
srem myset b //删除元素
smembers myset //列出所有元素
sismember myset a //判断是否在集合中
sinter myset myset2 //取交集
sunion myset myset2 //取并集
srandmember myset //随机取集合中的元素
(5)zset(sorted-set)
zadd mysort 70 zs 80 ls 90 ww //添加元素
zccore mysort ls //查询lsui应的值
zrange mysort 0 -1 //从小到大显示
zrevrange 0 -1 //从大到小显示
7.通用操作
keys * //查看所有的key
keys my* //操卡逊my开头的key
rename company newcompany //重命名company
expire company 1000 //设置超时时间1000秒
type company //查看类型
8.事务
multi //开启事务
exec //提交事务
discard //回滚事务
9.redis持久化
rdb
通过rdb临时文件,用临时文件代替持久化文件,实现持久化
(1)RDB触发机制分为手动触发和自动触发。
-
手动触发的两条命令:
SAVE
:阻塞当前Redis服务器,知道RDB过程完成为止。BGSAVE
:Redis 进程执行fork()
操作创建出一个子进程,在后台完成RDB持久化的过程。(主流)
-
自动触发的配置:
save 900 1 //服务器在900秒之内,对数据库执行了至少1次修改
save 300 10 //服务器在300秒之内,对数据库执行了至少10修改
save 60 1000 //服务器在60秒之内,对数据库执行了至少10000修改
// 满足以上三个条件中的任意一个,则自动触发 BGSAVE 操作
// 或者使用命令CONFIG SET 命令配置
(2)RDB的优缺点
优点:rdb是一个紧凑压缩的二进制文件,代表redis在某一时间的数据快照,非常适合备份
缺点:rdb没法做到实时持久化,因为bgsave每次运行都需要执行fork()创建子进程,属于重量级操作,成本高
aop
以日志的形式来记录每个写操作,有重写机制压缩文件内容
优点:可以实现秒级同步
缺点:相同数据量的aof文件大于rdb文件,占用磁盘空间
执行效率低于rdb(执行指令)
10.master/slave
redis-server /myredis/redis6380.conf
redis-cli -p 6380
目的:实现主从复制,读写分离
从库配置: slaveof 主库IP 主库端口
每次与主库断开后,重新启动变master,需重新连接才能变回slave
查看库配置:info replication
11.jedis
(1)事务
public class TestPing {
public static void main(String[] args) {
Jedis jedis = new Jedis("39.108.0.144",6379);
Transaction transaction = jedis.multi();
transaction.set("k4", "v4");
transaction.set("k5", "v5");
//transaction.discard();
transaction.exec();
}
}
(2)watch
watch命令就是标记一个键,在事务提交前该键被别人修改过,那事务就失败,这种情况通常可以在程序中再重新尝试一次
(模拟贷款)
public static boolean transMethod() throws InterruptedException {
Jedis jedis = new Jedis("39.108.0.144",6379);
int balance; //可用余额
int debt; //欠额
int amtToSubtract = 10;//消费金额
jedis.watch("balance");
Thread.sleep(7000);
//该线程休眠的时候在另一个线程set balance 5,该线程在watch
//到balance变化后重新读取redis中数据
balance = Integer.parseInt(jedis.get("balance"));
if(balance < amtToSubtract){
jedis.unwatch();
System.out.println("fail...");
return false;
}else{
System.out.println("transaction begin...");
Transaction transaction = jedis.multi();
transaction.decrBy("balance", amtToSubtract);
transaction.incrBy("debt", amtToSubtract);
transaction.exec();
System.out.println("-------------"+Integer.parseInt(jedis.get("balance")));
System.out.println("-------------"+Integer.parseInt(jedis.get("debt")));
return true;
}
}
public static void main(String[] args) throws InterruptedException {
transMethod();
}
}
(3)主从复制
public class TestMS {
public static void main(String[] args) {
Jedis master = new Jedis("39.108.0.144",6379);
Jedis slaver = new Jedis("39.108.0.144",6380);
slaver.slaveof("39.108.0.144",6379);
master.set("player", "kaka");
System.out.println(slaver.get("player"));
}
}