Elasticsearch 큰 데이터 세트를 처리 할 수 있도록 설계 전체 텍스트 검색 엔진이다. 설명에 따르면, 자연스럽게 그것을 저장하고 검색 응용 프로그램 로그에 사용합니다. 그리고 Logstash와 키바 함께,이 나의 이전 기사 중 일부의 탄성 스택 설명 된 강력한 솔루션의 일부입니다.
Elasticsearch하지 않은 응용 프로그램 로그 만 사용 시나리오를 보관하십시오. 그것은 일반적으로 보조 데이터베이스 응용 프로그램으로 사용, 그것은 주요 관계형 데이터베이스입니다. 당신은 전체 텍스트 검색 또는 더 이상 큰 데이터 세트를 수정할 수없는 경우에만 스토리지 애플리케이션의 역사를 많이 수행해야하는 경우이 방법은 특히 유용합니다. 물론,이 방법은 장점과 단점이 있습니다. 같은 데이터를 포함하는 두 개의 서로 다른 데이터 소스를 사용하는 경우, 먼저 동기화를 고려해야합니다. 당신은 몇 가지 옵션이 있습니다 : 관계형 데이터베이스 공급 업체에 따르면, 당신은 SQL 업데이트의 역사를 포함하는 바이너리 나 트랜잭션 로그를 사용할 수 있습니다. 이 방법은 로그, Elasticsearch에 다음 데이터를 읽을 일부 미들웨어가 필요합니다. 당신은 항상 데이터베이스 측의 전체 책임을 이동할 수 있습니다 (플립 플롭) 또는 Elasticsearch 끝 (JDBC 플러그인).
데이터 구조 : 아무리 당신이 Elasticsearch로 데이터를 가져 오는 방법, 우리는 또 다른 문제를 고려하지해야합니다. 관계형 데이터베이스의 데이터는 여러 테이블에 분산 할 수있다. 당신이 Elasticsearch를 사용하려는 경우, 당신은 하나의 형식으로 저장해야합니다. 그것은 더 많은 디스크 공간 사용으로 이어질 수있는 중복 데이터를 유지하는 당신을 강제로. 상응하는 관계형 데이터베이스보다 쿼리 Elasticsearch 빠른 쿼리, 그렇다면 물론,이 효과는 허용됩니다.
음,이 경우 도입 후 오랫동안 계속합니다. 봄 부팅 봄 데이터 저장소 및 Elasticsearch을 통해 상호 작용하는 쉬운 방법을 제공합니다.
1 Elasticsearch 지원 사용
규칙 봄 부팅함으로써, 우리는 Elasticsearch에 대한 지원을 활성화하는 상황에서 어떤 콩을 제공 할 필요가 없습니다. 우리는 pom.xml 파일에 다음 종속성을 추가해야합니다 :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
기본적으로 응용 프로그램은 로컬 호스트에 Elasticsearch에 연결을 시도합니다. 우리가 또 다른 대상 URL을 사용하는 경우, 우리는 구성 설정에서 오버라이드 (override) 할 필요가있다. 이것은 기본 클러스터 이름과 주소, 그리고 도커 용기 Elasticsearch의 시작의 주소를 우선 우리의 application.yml 파일의 조각입니다 :
spring:
data:
elasticsearch:
cluster-name: docker-cluster
cluster-nodes: 192.168.1.100:9300
응용 프로그램 할 수있는 건강 엔드 포인트 봄 부팅 액추에이터 상태 모니터링 Elasticsearch 연결하여. 첫째, 당신은 다음과 같은 메이븐 의존성을 추가해야합니다 :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
상태 검사는 기본적으로 사용, 자동 Elasticsearch 검사를 구성합니다. 그러나,이 Elasticsearch 나머지 API 클라이언트 실행에 의해 확인됩니다. 이 경우, 우리는 REST를 사용하는 클라이언트의 주소를 설정의 속성 spring.elasticsearch.rest.uris- 책임을 재정의해야합니다 :
spring:
elasticsearch:
rest:
uris: http://192.168.1.100:9200
2 Elasticsearch를 실행
우리의 테스트를 위해, 우리는 개발 모드에서 단일 노드의 Elasticsearch 예를 실행해야합니다. 평소와 같이, 우리는 부두 노동자 컨테이너를 사용합니다. 이것은 도커 최대 컨테이너와 9200 개 및 9300 포트는 명령에 따라 만들어진 public입니다.
$ docker run -d --name elasticsearch -p 9200 : 9200 -p 9300 : 9300 -e "discovery.type=single-node" elasticsearch: 6.6.2
봄 데이터 라이브러리의 3 건설
Elasticsearch 저장소를 사용하려면, 우리는 메인 클래스의 @EnableElasticsearchRepositories의 의견이나 구성 클래스를 사용합니다 :
@SpringBootApplication
@EnableElasticsearchRepositories
public class SampleApplication { ... }
다음 단계는 확장 CrudRepository 저장소 인터페이스를 만드는 것입니다. 여기에는 저장 또는 findById 메소드와 같은 몇 가지 기본 작업을 제공합니다. 당신은 몇 가지 추가 방법을 찾으려면, 당신은 인터페이스의 새 명명 방법은 봄 데이터 다음 정의해야합니다.
public interface EmployeeRepository extends CrudRepository<Employee, Long> {
List<Employee> findByOrganizationName(String name);
List<Employee> findByName(String name);
}
4 빌드 문서
관련 개체 (조직, 부서) 단일 직원 개체를 포함하는 우리의 육체적 인 관계 타일 구조. 당신은 비교하고 RDBMS의 관련 그룹 테이블에 대한 뷰를 만들려면이 방법을 사용할 수 있습니다. 봄 데이터 Elasticsearch 명명법에서 문서가 하나의 객체로 저장됩니다. 따라서 @Document 주석 객체를 사용하는 것이 필요하다. 또한 대상 인덱스 이름, 유형을 설정해야하고, ID는 Elasticsearch입니다. 주석 @Field 다른 맵을 구성 할 수 있습니다.
@Document(indexName = "sample", type = "employee")
public class Employee {
@Id
private Long id;
@Field(type = FieldType.Object)
private Organization organization;
@Field(type = FieldType.Object)
private Department department;
private String name;
private int age;
private String position;
// Getters and Setters ...
}
5 개 초기화 데이터
서론에서 언급 한 바와 같이, 당신은 Elasticsearch 주된 이유는 많은 데이터를 처리 할 필요가있다 사용하기로 결정 할 수 있습니다. 따라서 우리의 테스트 Elasticsearch 노드를 채우기 위해 많은 문서를 사용하는 것이 가장 좋습니다. 당신이 한 번에 많은 문서를 삽입 할 경우에, 당신은 대량 API를 사용해야합니다. 대량 API 색인 / 삭제 작업의 숫자의 구현은 하나의 API 호출로 가능하다 할 수 있습니다. 이것은 크게 인덱싱 속도를 향상시킬 수 있습니다. 당신은 봄 데이터 ElasticsearchTemplate 콩을 사용하여 대량의 작업을 수행 할 수 있습니다. 또한 자동으로 봄 부팅에서 구성 할 수 있습니다. 템플릿 인덱스 입력 매개 변수로 쿼리의 목록을 것이다 bulkIndex 방법을 제공한다. 이것은 응용 프로그램 시작 빈에서 샘플 테스트 데이터에 삽입 수행됩니다 :
public class SampleDataSet {
private static final Logger LOGGER = LoggerFactory.getLogger(SampleDataSet.class);
private static final String INDEX_NAME = "sample";
private static final String INDEX_TYPE = "employee";
@Autowired
EmployeeRepository repository;
@Autowired
ElasticsearchTemplate template;
@PostConstruct
public void init() {
for (int i = 0; i < 10000; i++) {
bulk(i);
}
}
public void bulk(int ii) {
try {
if (!template.indexExists(INDEX_NAME)) {
template.createIndex(INDEX_NAME);
}
ObjectMapper mapper = new ObjectMapper();
List<IndexQuery> queries = new ArrayList<>();
List<Employee> employees = employees();
for (Employee employee : employees) {
IndexQuery indexQuery = new IndexQuery();
indexQuery.setId(employee.getId().toString());
indexQuery.setSource(mapper.writeValueAsString(employee));
indexQuery.setIndexName(INDEX_NAME);
indexQuery.setType(INDEX_TYPE);
queries.add(indexQuery);
}
if (queries.size() > 0) {
template.bulkIndex(queries);
}
template.refresh(INDEX_NAME);
LOGGER.info("BulkIndex completed: {}", ii);
} catch (Exception e) {
LOGGER.error("Error bulk index", e);
}
}
// sample data set implementation ...
}
당신이 시작시에 데이터를 삽입 할 필요가없는 경우 프로세스를 비활성화 false로 사용할 수에서, 당신은 변경 초기 가져 오기 속성 수 있습니다. 이 SampleDataSet 빈 선언입니다 :
@Bean
@ConditionalOnProperty("initial-import.enabled")
public SampleDataSet dataSet() {
return new SampleDataSet();
}
6 개 데이터보기 및 실행 쿼리
사용하지 bean이 확장 인덱스에 대한 책임을지지 않습니다, 당신은 샘플 응용 프로그램을 시작한다고 가정하고, 모든 데이터가 Elasticsearch 노드에 삽입 될 때까지 몇 시간을 기다릴만큼 인내심을 가지고, 지금 100M 직원들에게 문서의 유형을 포함하고 있습니다. 클러스터 디스플레이에 대한 일부 정보는 가치가있다. 당신은이 작업을 수행 할 Elasticsearch 쿼리를 사용할 수 있습니다 당신은 또한 ElasticHQ로 사용할 수있는 GUI 도구를 다운로드 할 수 있습니다. 공교롭게도, ElasticHQ은 도커 용기로 사용할 수 있습니다. 당신은 ElasticHQ 컨테이너를 시작하려면 다음 명령을 수행해야합니다 :
$ docker run -d --name elastichq -p 5000:5000 elastichq/elasticsearch-hq
ElasticHQ, 포트 5000 GUI를 통해 웹 브라우저 액세스를 시작한 후. 자사의 웹 콘솔은 클러스터링, 인덱스 및 기본 정보에 대한 정보가 쿼리의 실행을 허용합니다. 당신은 당신은 통계 주요 대시 보드로 리디렉션됩니다, Elasticsearch 노드 주소를 입력해야합니다. 이 메인 계기판을 ElasticHQ된다.
당신이 볼 수 있듯이, 우리는 샘플라는 이름의 인덱스가 5 개 조각으로 나누어 져 있습니다. 이 봄 데이터 @Document이 파편 필드가 그것을 커버하기 위해 사용될 수있다 제공하는 기본이다. 클릭 한 후 우리는 인덱스 관리 패널로 이동할 수 있습니다. 당신은 캐시 또는 새로 고침 인덱스를 해결하는 것과 같이 인덱스에 대해 특정 작업을 수행 할 수 있습니다. 또한 모든 통계 조각을 볼 수 있습니다.
현재 테스트를 위해, 나는 2,500에 대한 문서의 직원 유형 (공간 3GB의에 대해)이있다. 우리는 몇 가지 테스트 쿼리를 수행 할 수 있습니다. 직원 이름의 GET / 직원 / {이름}과 조직 이름 GET / 직원 / 조직 / {조직 이름}에 의한 : 나는 검색을위한 두 개의 엔드 포인트를 개시되어있다. 결과는 압도적하지 않습니다. 나는 관계형 데이터베이스가 동일한 결과를 얻을 수 있습니다 동일한 양의 데이터를 사용하여 생각합니다.
7 테스트
음, 우리는 대용량 데이터 세트 및 일부 수동 테스트의 개발을 완료했습니다. 지금, 그것은 내장 때 일부 통합 테스트 실행을 만들 수있는 시간이다. 우리는 시험의 JUnit 라이브러리 중에 자동으로 도커 컨테이너 데이터베이스를 시작하기 위해 허가를 사용할 수 있습니다 - Testcontainers을. 사용 Testcontainers 프레임 워크 스프링 통합 테스트 볼트와 포스트 그레스와이 라이브러리에 대한 자세한 내용은 자신의 사이트 https://www.testcontainers.org 또는 내 이전 문서를 참조하십시오. 다행히 Testcontainers는 Elasticsearch을 지원합니다. 시험 범위에서 활성화하려면 먼저 pom.xml 파일에 다음 종속성을 추가해야합니다
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>elasticsearch</artifactId>
<version>1.11.1</version>
<scope>test</scope>
</dependency>
다음 단계는 포인트 나 Elasticsearch 컨테이너 @ClassRule @Rule 빈을 정의하는 것입니다. 각 테스트 클래스 전에 자동으로 시작 또는 주석의 사용에 의존하기 전에. 출판 포트 번호가 자동으로 그 값 속성 spring.data.elasticsearch.cluster-노드를 설정해야합니다 생성됩니다. 이것은 우리의 JUnit 통합 테스트의 완전한 실현이다 :
@RunWith(SpringRunner.class)
@SpringBootTest
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class EmployeeRepositoryTest {
@ClassRule
public static ElasticsearchContainer container = new ElasticsearchContainer();
@Autowired
EmployeeRepository repository;
@BeforeClass
public static void before() {
System.setProperty("spring.data.elasticsearch.cluster-nodes", container.getContainerIpAddress() + ":" + container.getMappedPort(9300));
}
@Test
public void testAdd() {
Employee employee = new Employee();
employee.setId(1L);
employee.setName("John Smith");
employee.setAge(33);
employee.setPosition("Developer");
employee.setDepartment(new Department(1L, "TestD"));
employee.setOrganization(new Organization(1L, "TestO", "Test Street No. 1"));
employee = repository.save(employee);
Assert.assertNotNull(employee);
}
@Test
public void testFindAll() {
Iterable<Employee> employees = repository.findAll();
Assert.assertTrue(employees.iterator().hasNext());
}
@Test
public void testFindByOrganization() {
List<Employee> employees = repository.findByOrganizationName("TestO");
Assert.assertTrue(employees.size() > 0);
}
@Test
public void testFindByName() {
List<Employee> employees = repository.findByName("John Smith");
Assert.assertTrue(employees.size() > 0);
}
}
개요
이 기사에서는 배울 것이다 :
-
Elasticsearch를 실행 도커의 로컬 인스턴스를 사용하여
-
봄 부팅 응용 프로그램 통합 및 Elasticsearch
-
봄 데이터 저장소를 사용하여 데이터를 저장하고 간단한 쿼리를 수행하는
-
봄 데이터 ElasticsearchTemplate 사용자가 인덱스에 일괄 작업을 수행 할 수
-
ElasticHQ 모니터 클러스터를 사용하여
-
使用Testcontainers为Elasticsearch构建自动集成测试 示例应用程序源代码通常在GitHub上的sample-spring-elasticsearch。
本文来源于微信公众号 java微技术