ElasticSearch教程(详解版)

news2024/11/15 16:58:42

        本篇博客将向各位详细介绍elasticsearch,也算是对我最近学完elasticsearch的一个总结,对于如何在Kibana中使用DSL指令,本篇文章不会进行介绍,这里只会介绍在java中如何进行使用,保证你看完之后就会在项目中进行上手,那我们开始本篇教程吧~

什么是ElasticSearch

  • Elasticsearch,基于lucene.分布式的Restful实时搜索和分析引擎(实时)
  • 分布式的实时文件存储,每个字段都被索引并可被搜索
  • 高扩展性,可扩展至上百台服务器,处理PB级结构化或非结构化数据
  • Elasticsearch用于全文检索,结构化搜索,分析/合并使用

ElasticSearch是如何做到这么快的

  • 分布式存储:ElasticSearch把数据存储在多个节点上,从而减少单个节点的压力,从而提高性能
  • 索引分片:ElasticSearch把索引分成多个分片,这样可以让查询操作并行化,从而提高性能
  • 全文索引:ElasticSearch把文档转换成可搜索的结构化数据,从而提高效率
  • 倒排索引:ElasticSearch将文档进行分词处理,把每个词在哪个文档中出现过进行映射,并存储这些信息,从而在搜索时,查询这些分词和搜索这些分词存在在哪些文档中,提高查询效率
  • 异步请求处理:ElasticSearch能够在请求到达时立即返回,避免长时间等待,提高效率

全文索引和倒排索引是什么

        全文检索是指计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。全文搜索搜索引擎数据库中的数据。

  • 优点:

    • 可以给多个字段创建索引

    • 根据索引字段搜索、排序速度非常快

  • 缺点:

    • 根据非索引字段,或者索引字段中的部分词条查找时,只能全表扫描。

        倒排索引就和传统的索引结构相反,传统的索引是由文档组成的,每个文档中都包含了若干个词汇,然后根据这些词汇简历索引。而倒排索引则与其相反,倒排索引由词汇构成,每个词汇对应若干个文档,然后根据这些文档建立索引。

  • 优点:

    • 根据词条搜索、模糊搜索时,速度非常快

  • 缺点:

    • 只能给词条创建索引,而不是字段

    • 无法根据字段做排序

ElasticSearch和Mysql之间的映射关系

Mysql类型       ElasticSearch类型说明
VARCHARtext、keyword根据是否需要使用全文搜索或精确搜索选择使用text或keyword
CHAR        

keyword                       

通常映射为keyword,因为它们存储较短的、不经常变化的字符序列
BLOB/TEXT        text大文本块使用text,适用于全文检索
INT,BIGINTlong大多数整数型使用long,以支持更大的数值
TINYINTbyte较小的整数可以映射为byte类型
DECIMAL,FLOAT,DOUBLEdouble,float
DATE,DATETIME,TIMESTAMPdate
BOOLEANboolean

倒排索引建立步骤

es中建立倒排索引需要两步,首先对文档进行分词,其次建立倒排索引

分词

        分词的意思大概就是对文档中的数据通过es的分词器进行分割成一个个词项,比如 “我是银氨溶液” 这句话,经过分词过后就是 “我”、“是”、“银氨”、“溶液”,当然es的分词器分为ik_smart分词器和ik_max_word分词,所以实际操作时这句话会被分解为不同的词段。

es中的一些概念

        文档

        elasticsearch是面向文档(Document)存储的,可以是数据库中的一条商品数据,一个订单信息。文档数据会被序列化为json格式后存储在elasticsearch中。

        字段

Json文档中往往包含很多的字段(Field),类似于数据库中的列。

        索引

索引(Index),就是相同类型的文档的集合。因此,我们可以把索引当做是数据库中的表。

        映射

        数据库的表会有约束信息,用来定义表的结构、字段的名称、类型等信息。因此,索引库中就有映射(mapping),是索引中文档的字段约束信息,类似表的结构约束。

对照图表:

MySQLElasticsearch说明
TableIndex索引(index),就是文档的集合,类似数据库的表(table)
RowDocument文档(Document),就是一条条的数据,类似数据库中的行(Row),文档都是JSON格式
ColumnField字段(Field),就是JSON文档中的字段,类似数据库中的列(Column)
SchemaMappingMapping(映射)是索引中文档的约束,例如字段类型约束。类似数据库的表结构(Schema)
SQLDSLDSL是elasticsearch提供的JSON风格的请求语句,用来操作elasticsearch,实现CRUD

RestAPI

首先,在这篇文章中不会将所有api都介绍完,所以这了贴上官方文档的地址,以共各位查看:

ElasticSearch官方文档

这里需要先引入es的依赖

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>

同时,你需要在pom文件中修改es的版本和你本地的一样

 

然后,我们需要把es注入到spring容器中

@Configuration
public class ElasticSearchClientConfig {

    @Bean
    public RestHighLevelClient restHighLevelClient(){
        RestHighLevelClient client=new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("127.0.0.1", 9200, "http")
                )
        );
        return client;
    }
}

 准备工作完成之后就可以开始接下来的学习啦~

索引的CRUD操作

索引的操作较为简单,而且项目中实际都是对文档进行操作,所以我这里贴出索引的相关操作代码,并做出解释,各位可以了解一下

 @Autowired
    @Qualifier("restHighLevelClient")
    private RestHighLevelClient client;

    //    测试索引的创建  Request
    @Test
    void testCreateIndex() throws Exception {
//        1、创建索引请求
        CreateIndexRequest request = new CreateIndexRequest("yinan_index");
//       2、客户端执行请求,请求后获得响应
        CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
        System.out.println(createIndexResponse);
    }

    //    测试获取索引
    @Test
    void testGetIndex() throws IOException {
        GetIndexRequest getIndex = new GetIndexRequest("yinan_index");
        boolean exists = client.indices().exists(getIndex, RequestOptions.DEFAULT);
        System.out.println(exists);
    }

    //    删除索引
    @Test
    void testDeleteIndex() throws Exception {
        DeleteIndexRequest request = new DeleteIndexRequest("yinan_index");
        AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
        System.out.println(delete.isAcknowledged());
    }

其中indices中包含了操作索引库的所有方法,在创建索引的时候如果有多个字段,可以提前写好 一个字符串常量,例如:

   public static final String MAPPING_TEMPLATE = "{\n" +
            "  \"mappings\": {\n" +
            "    \"properties\": {\n" +
            "      \"id\": {\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"name\":{\n" +
            "        \"type\": \"text\",\n" +
            "        \"analyzer\": \"ik_max_word\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"address\":{\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"index\": false\n" +
            "      },\n" +
            "      \"price\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"score\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"brand\":{\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"city\":{\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"starName\":{\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"business\":{\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"location\":{\n" +
            "        \"type\": \"geo_point\"\n" +
            "      },\n" +
            "      \"pic\":{\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"index\": false\n" +
            "      },\n" +
            "      \"all\":{\n" +
            "        \"type\": \"text\",\n" +
            "        \"analyzer\": \"ik_max_word\"\n" +
            "      }\n" +
            "    }\n" +
            "  }\n" +
            "}";

 然后将新增索引中的代码修改成以下:

文档的CRUD操作

对于文档这里将重点介绍查询的相关方法,其它操作只做简单介绍。

查询操作
MatchAll
/**
     * 查询全部
     */
    @Test
    void testMatchAll() throws IOException {
        //1.准备request
        SearchRequest request = new SearchRequest("hotel");
        //2.准备参数
        request.source().query(QueryBuilders.matchAllQuery());

        //3.发起请求得到响应结果
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        //4.解析响应
        handleResponse(response);
    }

结果如下:

 从结果我们也可以看到这个api是查询所有数据的方法,但是控制台只显示了10条数据,这是因为这个方法自动进行分页处理,每页10条数据。

Match
   /**
     * 全文检索
     */
    @Test
    void testMatch() throws IOException {
        //1.准备request
        SearchRequest request = new SearchRequest("hotel");
        //2.准备参数
        request.source().query(QueryBuilders.matchQuery("all","如家"));
        //3.发起请求得到响应结果
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        //4.解析响应
        handleResponse(response);
    }

结果:

match用来做基本的模糊匹配,在es中会对文本进行分词,在match查询的时候也会对查询条件进行分词,然后通过倒排索引找到匹配的数据。

term
 @Test
    void testMatch() throws IOException {
        //1.准备request
        SearchRequest request = new SearchRequest("hotel");
        //2.准备参数
//        request.source().query(QueryBuilders.matchQuery("all","如家"));
        request.source().query(QueryBuilders.termQuery("city","北京"));
        //3.发起请求得到响应结果
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        //4.解析响应
        handleResponse(response);
    }

结果:

 从结果来看,term是做精确查询的,所以一般可以用在查询某个具体的属性的时候

multiMatchQuery
 @Test
    void testMatch() throws IOException {
        //1.准备request
        SearchRequest request = new SearchRequest("hotel");
        //2.准备参数
//        request.source().query(QueryBuilders.matchQuery("all","如家"));
//        request.source().query(QueryBuilders.termQuery("city","北京"));
        request.source().query(QueryBuilders.multiMatchQuery("如家", "city", "name"));
        //3.发起请求得到响应结果
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //4.解析响应
        handleResponse(response);
    }

 结果:

    multiMatchQuery接受两个参数,一个是text,一个是fieldname,前者表示要查询的内容,后者表示要在哪些字段中进行查询,如果后者中的数据只有一个,那该方法和matchall一致,如果后者有多个,那查询的结果必须要满足其中的一个。
rangeQuery
 @Test
    void testMatch() throws IOException {
        //1.准备request
        SearchRequest request = new SearchRequest("hotel");
        //2.准备参数
//        request.source().query(QueryBuilders.matchQuery("all","如家"));
//        request.source().query(QueryBuilders.termQuery("city","北京"));
//        request.source().query(QueryBuilders.multiMatchQuery("如家", "city", "name"));
                request.source().query(QueryBuilders.rangeQuery("price").gte(100).lte(150));
        //3.发起请求得到响应结果
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //4.解析响应
        handleResponse(response);
    }

结果:

该方法主要做范围查询,相当于sql语句中的between....and...

布尔查询
/**
     * 布尔查询
     * @throws IOException
     */
    @Test
    void testBool() throws IOException {
        //1.准备request
        SearchRequest request = new SearchRequest("hotel");
        //2.准备参数
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        boolQuery.must(QueryBuilders.termQuery("city","北京"));
        boolQuery.filter(QueryBuilders.rangeQuery("price").lte(300));

        request.source().query(boolQuery);

        //3.发起请求得到响应结果
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        System.out.println( "========"+response.getHits());

        //4.解析响应
        handleResponse(response);

    }


 /**
     * 解析响应结果
     * @param response
     */
    private void handleResponse(SearchResponse response) {
        SearchHits searchHits = response.getHits();
        //总条数
        long total = searchHits.getTotalHits().value;

        System.out.println("共搜索到"+total+"条数据");
        //文档数组
        SearchHit[] hits = searchHits.getHits();
        //遍历
        for (SearchHit hit : hits){
            //获取文档source
            String json = hit.getSourceAsString();
            //反序列化
            HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
            //获取高亮结果
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if(!CollectionUtils.isEmpty(highlightFields)){
                //根据字段名获取高亮结果
                HighlightField highlightField = highlightFields.get("name");
                if(highlightField != null){
                    //获取高亮值
                    String name = highlightField.getFragments()[0].string();
                    //替换
                    hotelDoc.setName(name);
                }
            }
            System.out.println("hotDoc = "+hotelDoc);
        }

这里简单说一下怎么得到的 handleResponse函数

通过以上图片我们就不难看出 response的响应结构,因此我们就可以具体推出相关信息,所以没有学习过在Kibana上使用DSL指令的朋友可以先去学习一下,然后再来运用到java中事半功倍。

当然,如果你只需要获取数据和总条数,可以修改成以下形式:

 private PageResult handleResponse(SearchResponse response) {
        SearchHits hits = response.getHits();
        long total = hits.getTotalHits().value;
        SearchHit[] searchHits = hits.getHits();
        List<HotelDoc> hotels = new ArrayList<>();
        for (SearchHit searchHit : searchHits) {
            String source = searchHit.getSourceAsString();
//            反序列化
            HotelDoc hotelDoc = JSON.parseObject(source, HotelDoc.class);
            hotels.add(hotelDoc);
        }
        return new PageResult(total,hotels);
    }
分页和排序 对结果的处理
/**
     * 分页和排序 对结果的处理
     */
    @Test
    void testPageAndSort() throws IOException {

        int page = 1,size = 5;
        //1.准备request
        SearchRequest request = new SearchRequest("hotel");
        //2.准备参数
        request.source().query(QueryBuilders.matchAllQuery());
        //排序
        request.source().sort("price", SortOrder.ASC);
        //分页
        request.source().from((page-1)*size).size(size);

        //3.发起请求得到响应结果
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        //4.解析响应
        handleResponse(response);
    }

当然,还有其它一些api这里还没有介绍到,各位可以去官网进行查看详细文档说明~

 添加文档
@Data
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
    private String name;
    private Integer age;
}
 @Test
    void testAddDocument() throws IOException {
//        1、创建对象
        User user = new User("yinan", 20);
//        2、创建请求
        IndexRequest request = new IndexRequest("yinan_index");
//        规则  put /yinan_index/_doc/1
        request.id("1");
        request.timeout(TimeValue.timeValueSeconds(1));
        request.timeout("1s");
//        将数据放入请求  json
        request.source(JSON.toJSONString(user), XContentType.JSON);
//        客户端发送请求,获取相应的结果
        IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);

        System.out.println(indexResponse.toString());
        System.out.println(indexResponse.status());  //对应我们命令返回状态

    }
批量添加文档
 @Test
    void testBulkRequest() throws Exception {
        BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("10s");
        ArrayList<User> userList = new ArrayList<>();
        userList.add(new User("yinan1", 21));
        userList.add(new User("yinan1", 21));
        userList.add(new User("yinan3", 26));
        userList.add(new User("yinan4", 24));
        userList.add(new User("yinan5", 27));
        userList.add(new User("yinan12", 20));

        for (int i = 0; i < userList.size(); i++) {
            bulkRequest.add(
                    new IndexRequest("yinan_index")
                            .id("" + (i + 1))
                            .source(JSON.toJSONString(userList.get(i)), XContentType.JSON)
            );
        }
        BulkResponse itemResponses = client.bulk(bulkRequest, RequestOptions.DEFAULT);
        System.out.println(itemResponses.hasFailures());
    }
修改文档
 @Test
    void testUpdateDocument() throws Exception {
        UpdateRequest request = new UpdateRequest("yinan_index", "1");
        request.timeout("1s");
        User user = new User("yinan_update", 21);
        request.doc(JSON.toJSONString(user), XContentType.JSON);
        UpdateResponse updateResponse = client.update(request, RequestOptions.DEFAULT);
        System.out.println(updateResponse.status());
    }
删除文档
   @Test
    void testDeleteDocument() throws Exception {
        DeleteRequest request = new DeleteRequest("yinan_index", "1");
        request.timeout("1s");
        DeleteResponse deleteResponse = client.delete(request, RequestOptions.DEFAULT);
        System.out.println(deleteResponse.status());
    }

以上就是对es部分api的讲解,当然只看api使用是远远不够的,所以我们需要做一个小训练来巩固我们学习的东西。

资料已经置顶在本篇博客,有需要的请自取~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1800610.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java学习-JDBC(一)

JDBC 概念 JDBC(Java Database Connectivity)Java数据库连接JDBC提供了一组独立于任何数据库管理系统的APIJava提供接口规范&#xff0c;由各个数据库厂商提供接口的实现&#xff0c;厂商提供的实现类封装成jar文件&#xff0c;也就是我们俗称的数据库驱动jar包JDBC充分体现了…

IP SSL使用率增长有利于网络安全防护!

目录 IP的特殊性 IP证书的作用原理&#xff1a; 申请IP证书的基本条件&#xff1a; 申请IP SSL证书&#xff1a; 对于SSL证书来说&#xff0c;很多朋友应该并不陌生&#xff0c;目前SSL证书广泛应用在域名服务器上&#xff0c;所以大家最熟悉的证书类型可能就是单域名SSL证…

element-plus 的icon 图标的使用

element-plus的icon 已经独立出来了&#xff0c;需要单独安装 1. npm安装 icon包 npm install element-plus/icons-vue2.注册到全局组件中 同时注册到全局组件中&#xff0c;或者按需单独引入&#xff0c;这里只介绍全局引入。 import { createApp } from vue import { cre…

(UE4.26)UE4的FArchive序列化入门

前言 序列化(Serialize)和反序列化(UnSerialize)是程序领域常见的概念。对于这两个词汇我理解的是 序列化(Serialize): 变量值(int, float, string等基本类型, 或者Array&#xff0c;Map&#xff0c;或者更复杂的复合体)存储为一个文件(二进制流, 二进制文件, json, xml等格式…

使用 PAI-DSW x Free Prompt Editing图像编辑算法,开发个人AIGC绘图小助理

教程简述 在本教程中&#xff0c;您将学习在阿里云交互式建模平台PAI-DSW x Free Prompt Editing&#xff08;CVPR2024中选论文算法&#xff09;图像编辑算法&#xff0c;开发个人AIGC绘图小助理&#xff0c;实现文本驱动的图像编辑功能单卡即可完成AIGC图片风格变化、背景变化…

277 基于MATLAB GUI火灾检测系统

基于MATLAB GUI火灾检测系统&#xff0c;可以实现图片和视频的火苗检测。火焰识别的三个特征&#xff1a;1个颜色特征&#xff0c;2个几何特征颜色特征&#xff1a;HSV颜色空间下&#xff0c;对三个通道值进行阈值滤波&#xff0c;几何特征1&#xff1a;长宽比&#xff0c;几何…

k8s——pod控制器

一、pod控制器定义 Pod控制器&#xff0c;又称之为工作负载&#xff08;workload&#xff09;&#xff0c;是用于实现管理pod的中间层&#xff0c;确保pod资源符合预期的状态&#xff0c;pod的资源出现故障时&#xff0c;会尝试进行重启&#xff0c;当根据重启策略无效&#xf…

NIST 电子病历中的疾病列表部分的认证

美国国家标准与技术研究院&#xff08;National Institute of Standards and Technology&#xff0c;NIST&#xff09;对电子病历的认证 分几个阶段&#xff0c;每个阶段又分门诊和住院&#xff0c;然后又分若干模块。下面是疾病列表的测试脚本。 170.302c_Problemlist Test …

(一)大数据基础练习题(66道选择题)

本文整理了大数据基础知识相关的练习题&#xff0c;共66道&#xff0c;适用于想巩固大数据基础的同学。来源&#xff1a;如荷学数据科学题库&#xff08;技术专项-大数据&#xff09;。 1&#xff09; 2&#xff09; 3&#xff09; 4&#xff09; 5&#xff09; 6&#xff09;…

高考分数查询结果自动推送至微信

又是一年高考时&#xff0c;祝各位学子金榜题名&#xff0c;天遂人愿! 在您阅读以下内容时&#xff0c;请注意&#xff1a;各省查分API接口可能不相同&#xff0c;本人仅就技术层面谈谈&#xff0c; 纯属无聊&#xff0c;因为实用意义不大&#xff0c;毕竟一年一次&#xff0c;…

【机器学习】XGBoost: 强化学习与梯度提升的杰作

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 XGBoost: 强化学习与梯度提升的杰作引言1. XGBoost概览1.1 什么是XGBoost&#…

27 ssh+scp+nfs+yum进阶

ssh远程管理 ssh是一种安全通道协议&#xff0c;用来实现字符界面的远程登录。远程复制&#xff0c;远程文本传输。 ssh对通信双方的数据进行了加密。 用户名和密码登录 密钥对认证方式&#xff08;可以实现免密登录&#xff09; ssh 22 网络层 传输层 数据传输的过程中是…

【PL理论】(8) F#:列表高阶函数之 filter 函数 | 内联谓词函数 | 链式操作:先过滤再映射

&#x1f4ad; 写在前面&#xff1a;上一章中&#xff0c;我们详细讲解了列表的合并&#xff0c;本章我们来详细讲解一下列表的过滤&#xff0c;在 F# 中&#xff0c;过滤列表是指从列表中提取满足某个条件的元素&#xff0c;形成一个新的列表。这个操作通常使用 List.filter 函…

第R3周:天气预测

&#x1f368; 本文为&#x1f517;365天深度学习训练营中的学习记录博客 &#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 &#x1f680; 文章来源&#xff1a;K同学的学习圈子 目录 我的环境 语言环境&#xff1a;python3.8.18编译器&#xff1a;jupyter not…

用HTML实现拓扑面,动态4D圆环面,可手动调节,富有创新性的案例。(有源代码)

文章目录 前言一、示例二、目录结构三、index.html&#xff08;主页面&#xff09;四、main.js五、Tour4D.js六、swissgl.js七、dat.gui.min.js八、style.css 前言 如果你觉得对代码进行复制粘贴很麻烦的话&#xff0c;你可以直接将资源下载到本地。无需部署&#xff0c;直接可…

如何利用Varjo混合现实技术改变飞机维修训练方式

自2017年以来&#xff0c;总部位于休斯顿的HTX实验室一直在推进混合现实技术&#xff0c;与美国空军密切合作&#xff0c;通过其EMPACT平台提供可扩展的沉浸式飞机维护虚拟现实培训。 虚拟和混合现实对维修训练的好处&#xff1a; l 实践技能&#xff1a;提供一个非常接近真实场…

独享IP VS 原生IP,二者的区别与定义详解

原生IP&#xff1a;原生IP是指由Internet服务提供商&#xff08;ISP&#xff09;直接分配给用户的IP地址&#xff0c;这些IP地址通常反映了用户的实际地理位置和网络连接。原生IP是用户在其所在地区或国家使用的真实IP地址&#xff0c;与用户的物理位置直接相关。在跨境电商中&…

Liunx环境下redis主从集群搭建(保姆级教学)02

Redis在linux下的主从集群配置 本次演示使用三个节点实例一个主节点&#xff0c;两个从节点&#xff1a;7000端口&#xff08;主&#xff09;&#xff0c;7001端口&#xff08;从&#xff09;&#xff0c;7002端口&#xff08;从&#xff09;&#xff1b; 主节点负责写数据&a…

Ghost Mirror

Ghost Mirror 操作系统镜像 windows servers linux Windows XP 老古董&#xff0c;唉 安装完重启一下 设置下BIOS 1小时内弄完3台。。。

【MMU】——页表映射示例

文章目录 页表映射示例一级页表二级页表二级页表的优势页表映射示例 一级页表 上图一级页表中假设以 4KB 物理页为映射单位,一个进程 4GB 的虚拟地址空间需要:4GB/4KB = 1MB 个页表项,每个页表项目占用 4 个字节所以每个一级页表需要 4MB 的存储空间,每个进程需要 4MB 的内…