0%

布隆过滤器

redis原生不自带布隆过滤器,需要自己去编译该插件进行安装

安装

从github进行下载https://github.com/RedisBloom/RedisBloom/tags,进入下载目录进行编译make,生成redisbloom.so文件

修改redis.conf加载插件 loadmodule /usr/local/myself/redis/module/RedisBloom-2.2.18/redisbloom.so,重启redis

基本命令

  • bf.add 添加元素

    1
    2
    3
    4
    127.0.0.1:6379> bf.add art user1
    (integer) 1
    127.0.0.1:6379> bf.add art user2
    (integer) 1
  • bf.exists 查询元素是否存在

    1
    2
    3
    4
    127.0.0.1:6379> BF.EXISTS art user3
    (integer) 0
    127.0.0.1:6379> BF.EXISTS art user1
    (integer) 1
阅读全文 »

web项目的目录结构

  • WEB-INF 存放class文件、jar文件和配置文件,对于用户来说该文件夹是不可见的
  • WEB-INF/web.xml web应用程序的描述文件,用来配置资源,如servlet、过滤器、监听器等
  • WEB-INF/classes 用于存放class文件,也是该web应用程序的类加载路径
  • WEB-INF/lib 用于存放第三方的类库jar文件
  • 其他资源文件存放到和WEB-INF同级的目录中

web应用程序只能访问到存放在classes和lib目录下的java类

web如何取得用户信息

之前说过SecurityContextHolder默认使用的是ThreadLocal来进行存储的,而且每次都会清除,但是web每次请求都会验证用户权限,这是如何做到的呢?

这是通过SecurityContextPersistenceFilter来实现的,每次请求过来都会session中来获取SecurityContext,然后设置到SecurityContextHolder中,请求结束后再清除掉

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;

if (request.getAttribute(FILTER_APPLIED) != null) {
// ensure that filter is only applied once per request
chain.doFilter(request, response);
return;
}

request.setAttribute(FILTER_APPLIED, Boolean.TRUE);


HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request,
response);
// 从session获取SecurityContext
SecurityContext contextBeforeChainExecution = repo.loadContext(holder);

try {
// 将SecurityContext存入SecurityContextHolder
SecurityContextHolder.setContext(contextBeforeChainExecution);

chain.doFilter(holder.getRequest(), holder.getResponse());

}
finally {
SecurityContext contextAfterChainExecution = SecurityContextHolder
.getContext();
// Crucial removal of SecurityContextHolder contents - do this before anything
// else.
SecurityContextHolder.clearContext();
// 存储SecurityContext
repo.saveContext(contextAfterChainExecution, holder.getRequest(),
holder.getResponse());
request.removeAttribute(FILTER_APPLIED);
}
}
阅读全文 »

存储表情符号

默认mysql的字符集是utf8,排序规则为 utf8_general_ci

1
INSERT INTO department (name) VALUES ('😄')

在存储表情的时候会报 1366 - Incorrect string value: '\xF0\x9F\x98\x84' for column 'name' at row 1, Time: 0.007000s

这时需要修改字符集

1
ALTER TABLE department MODIFY name varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '部门名称';

这时就可以了

utf8和utf8mb4的区别

MySQL中的utf8其实是utf8mb3,最多只用3个字节存储字符,存储不了表情。如果要支持表情,需要使用完整的utf8字符集utf8mb4,可用4个字节来存储

分页查询

之前在基本操作中说过分页查询使用from+size来进行查询,对于数据量不大的可以这么用,但是对于数据量大的深度分页这样会造成性能问题

from+size分页查询

size是返回的条数,from是跳过的条数

1
GET _search?size=20&from=100

或者使用dsl请求

1
2
3
4
5
6
GET _search

{
"size":20,
"from":100
}

这里是需要去每个分片去进行查询的,假如设置from为100,size为20,此时每个分片都需要先取出from+size=120条数据,然后将各分片数据聚合之后在进行一次全局排序,获取出120条数据,在从第100条开始,往后选20条数据。

如果翻页过深的话,需要从各分片筛选出大量的数据,那如何解决深度分页的问题呢?可以使用scroll游标

阅读全文 »