1、为什么要使用sql数据库(nosql数据库的优点)
处理需要集群的大小和性能的数据访问,使用更方便的数据交互方式提高应用程序开发的生产率
NoSQL 数据库相比于传统的关系型数据库的最大转变就是抛弃了关系模型,而是选择使用聚合数据模型。聚合数据模型的特点是把经常访问的数据放在一起,对于某个查询请求,能够在与数据库一次交互中将所有的数据都取出来。
NoSQL 数据库是分布式横向扩展技术。它们使用了分布式节点集(称为集群)来提供高度弹性扩展功能,让用户可以添加节点来动态处理负载。关系型数据库是纵向扩展,是集中式、共享一切的技术,只能通过增加更多昂贵的硬件来扩展。
易扩展、快速读写、成本低廉、架构灵活,没有复杂的关系、分布式计算
2、我们有四类sql数据库,各写一个产品的名字
键值数据库:Redis,适用场景:会话信息,用户配置信息,购物车
文档数据库:MongoDb,适用场景:事件记录,内容管理,博客平台,网站分析,实时分析,电子商务应用
列族数据库:HBase,BigTable适用场景:事件记录,内容管理,博客平台
不适合需要ACID事务的场合
图数据库:Neo4J,适用场景:社交网络,推荐引擎,基于位置的服务
3、解释五个redis参数的意思
databases:设定redis所允许的最大”db簇”的个数,默认为16个簇。
save 900 1:900 秒之后,且至少 1 次变更
appendonly:是否在每次更新操作后进行日志记录,如果不开启,可能会在断电时导致一段时间内的数据丢失。
maxmemory 1gb:Redis 实例最大占用内存
cluster-enable yes:开启集群模式
4、ACID是什么意思
A (Atomicity) 原子性:事务里的所有操作要么全部做完,要么都不做,事务成功的条件是事务里的所有操作都成功,只要有一个操作失败,整个事务就失败,需要回滚。
C (Consistency) 一致性:数据库要一直处于一致的状态,事务的运行不会改变数据库原本的一致性约束。
I (Isolation) 独立性:并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。
D (Durability) 持久性:一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。
5、在nosql中,CAP是什么意思?如何均衡CAP?
(1)它的意思是,一个分布式系统不能同时满足一致性,可用性和分区容错性这三个需求,最多只能同时满足两个。
一致性(Consistency):任何一个读操作总是能读取到之前完成的写操作结果,也就是在分布式环境中,多点的数据是一致的
可用性(Availability):每一个操作总是能够在确定的时间内返回,也就是系统随时都是可用的。
分区容忍性(Partition Tolerance): 在出现网络分区(比如断网)的情况下,分离的系统也能正常运行。
(2)对于一个分布式系统来说。P是基本要求,CAP三者中,只能在CA两者之间做权衡,无法通过降低C和A来提升P。要想提升系统的P,需要通过提升基础设施的稳定性来保障。
在涉及到钱财这样在同一时间所有节点数据完全相同的场景时,C必须保证。网络发生故障或者消息丢失等情况停止服务,等待所有数据全部一致了之后再让用户访问系统;
对于其它场景,普遍做法是要 AP,舍弃强一致性,保证最终一致性来保证数据安全。
6. BASE 是什么?含义?
基本可用性(BA):当分布式系统出现故障时,允许损失部分可用性,保证核心模块的可用性。
软状态(S):允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时。
最终一致性(E):系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。
BASE 理论其实就是对CAP理论的延伸和补充,主要是对AP的补充。牺牲数据的强一致性,来保证数据的可用性,虽然存在中间装填,但数据最终一致。
7. Redis 对等集群?
Redis 集群节点间采取Gossip协议进行通信。Gossip协议是由根节点发起,当一个根节点有状态需要更新到网络中的其他节点时,它会随机的选择周围几个节点散播消息,收到消息的节点也会重复该过程,直至最终网络中所有的节点都收到了消息。这种方式,数据的更新比较分散,更新请求会有一定的延迟,降低了压力。每个节点可能知道所有其他节点,也可能仅知道几个邻居节点,只要这些节可以通过网络连通,最终他们的状态都是一致的。
8. 一致性 Hash 算法?
一致性 Hash 算法是在 Hash 算法基础上,将整个 Hash 空间映射成一个虚拟的圆环,空间的取值范围为0到2的32次方-1,整个空间按顺时针方向组织,0和2的32次方-1在零点重合。对节点的请求用 Hash 算法算出对应的 Hash 值,根据 Hash 值的位置沿圆环顺时针查找,第一个找到的节点就是对应的处理请求节点。增加、删除节点或节点不可用时,受影响的数据仅仅时节点到其环空间中邻近一个的节点之间的数据,其它的都不会受到影响。
9、写出五个redis数据操作的主要命令
del key [key ...]:删除给定的一个或多个 key
set key value:将字符串值 value 关联到 key
get key:返回 key 所关联的字符串值
hget key field:返回哈希表 key 中给定域 field 的值
hset key field value:将哈希表 key 中的域 field 的值设为 value
PING:用于检测 redis 服务是否启动。
DEL key:用于key存在时删除
TYPR key:返回key所存储的类型
EXISTS key:检查给定key是否存在
10、键值数据库适合的场景两个
存储会话信息:通常来说,每一次网络会话都是唯一的,所以分配给它们的session id值也各不相同,如果应用程序原来要把session id存在磁盘或者关系型数据库中,用键值数据库可以更好,因为全部会话内容都可以用一条put请求来存放,而且只需一条Get请求就可以取得。
存储用户配置信息:几乎每位用户都有userid.username或者其他独特的属性,而且其配置信息也各自独立,这些内容可以全部放在一个对象里,以便只用一次get操作就可以获取某位用户的全部配置信息
存储购物车数据:电子商务网站的用户都与其购物车相绑定,由于购物车的内容要在不同时间,不同浏览器,不同电脑,不同会话中保持一致,所以可以把购物信息放在valuew属性中,将其绑定到userid这个键名上
11、四大类nosql数据库,各写一个使用的场景
键值数据库:购物车数据
文档数据库:网站分析与实时分析
列族数据库:分布式文件系统
图数据库:为客户推荐相关信息的推荐引擎
12. Redis Cluster 为什么使用 Hash Slot(对等节点为什么使用槽)?
统一抽象:存储在 Redis Cluster 中的所有 Key 都会经过 CRC16 计算校验和找到对应 Hash Slot。通过内存表对 Hash Slot 进行分片,为 Redis Cluster 中的每个节点指派不同数量的 Hash Slot 以控制不同节点负责的数据量和请求数;
方便迁移,数据的传输:Hash Slot 这种结构,使得从一个节点将 Hash Slot 移动到另一个节点时不会对其它的节点造成影响,所以这种迁移不会使 Redis Cluster 处于不可用的状态并且更加方便
1.用命令行搭建一主二从
redis-cli.exe -p 8888
127.0.0.1:8888> slaveof 127.0.0.1 6379
127.0.0.1:8888> exit
redis-cli.exe -p 8889
127.0.0.1:8889> slaveof 127.0.0.1 6379
127.0.0.1:8889> exit
增删查:改
import net.sf.json.JSONObject;
import com.UserDao.SerializeUtil;
import com.UserDao.UserVO;
import redis.clients.jedis.Jedis;
public class counter {
public static void main(String[] args) {
Jedis jedis = new Jedis("localhost", 6379);
//普通键值对存储查询删除
jedis.set("key", "value");
System.out.println(jedis.get("key"));
jedis.del("key");
// 对象的存储
UserVO student1 = new UserVO();
student1.setUserId("1");
student1.setPassWord("123456");
student1.setUserName("张三");
//方法一:序列化对象存储
byte[] stuSer = SerializeUtil.serizlize(student1);
jedis.set("stu1".getBytes(), stuSer);
System.out.println(SerializeUtil.deserialize(jedis.get("stu1".getBytes())));
jedis.del("stu1".getBytes());
//方法二:JSON存储
JSONObject stuJSON = JSONObject.fromObject(student1);
jedis.set("stu1", stuJSON.toString());
String re = jedis.get("stu1");
JSONObject json = JSONObject.fromObject(re);
UserVO output = (UserVO)JSONObject.toBean(json,UserVO.class);
System.out.println(output);
jedis.del("stu1");
//方法三:hash结构存储
jedis.hset("stu1", "UserId", student1.getUserId());
jedis.hset("stu1", "PassWord", student1.getPassWord());
jedis.hset("stu1", "UserName", student1.getUserName());
UserVO output2 = new UserVO();
output2.setUserId(jedis.hget("stu1", "UserId"));
output2.setPassWord(jedis.hget("stu1", "PassWord"));
output2.setUserName(jedis.hget("stu1", "UserName"));
System.out.println(output2);
jedis.del("stu1");
jedis.close();
}
}